Search code examples
javascriptunit-testingember.jssinonsinon-chai

Sinon how to stub method for unit testing a Async function


I am trying to write a unit test for an async function using mocha and sinon.js

Below is my test case

  describe('getOperations', function () {
    let customObj, store, someObj
    beforeEach(function () {
      someObj = {
        id: '-2462813529277062688'
      }
      store = {
        peekRecord: sandbox.stub().returns(someObj)
      }
    })
    it('should be contain obj and its ID', function () {
      const obj = getOperations(customObj, store)
      expect(obj).to.eql(someObj)
    })
  })

Below is the definition of the async function I am testing.

async function getOperations (customObj, store) {
  const obj = foo(topLevelcustomObj, store)
  return obj
}

function foo (topLevelcustomObj, store) {
    return store.peekRecord('obj', 12345)
}

The test case fails as the promise being return is rejected with a message

TypeError: store.query is not a function at Object._callee$.

The code I am testing is not calling store.query anywhere and also I have stubbed store.peekRecord also so not sure how it is getting called.


Solution

  • Your getOperations function use async syntax so that you need to use async/await in your test case. And, it works fine.

    E.g. index.ts

    export async function getOperations(customObj, store) {
      const obj = foo(customObj, store);
      return obj;
    }
    
    export function foo(customObj, store) {
      return store.peekRecord("obj", 12345);
    }
    

    index.test.ts:

    import { getOperations } from "./";
    import sinon from "sinon";
    import { expect } from "chai";
    
    describe("59639661", () => {
      describe("#getOperations", () => {
        let customObj, store, someObj;
        beforeEach(function() {
          someObj = {
            id: "-2462813529277062688",
          };
          store = {
            peekRecord: sinon.stub().returns(someObj),
          };
        });
        it("should pass", async () => {
          const obj = await getOperations(customObj, store);
          expect(obj).to.deep.eq(someObj);
        });
      });
    });
    

    Unit test result with 100% coverage:

      59639661
        #getOperations
          ✓ should pass
    
    
      1 passing (14ms)
    
    ---------------|----------|----------|----------|----------|-------------------|
    File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ---------------|----------|----------|----------|----------|-------------------|
    All files      |      100 |      100 |      100 |      100 |                   |
     index.test.ts |      100 |      100 |      100 |      100 |                   |
     index.ts      |      100 |      100 |      100 |      100 |                   |
    ---------------|----------|----------|----------|----------|-------------------|
    

    Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59639661