简体   繁体   中英

How do I resolve the outer promise inside a mocked function with Jest?

Here is my basic setup I'm trying to test.

First, Method I'm testing:

Thing.prototype.getStuff = function(){
   return new Promise((resolve, reject) => {
     // Bunch of business logic...
     this.getOtherStuff().then((data) => {
        // Perform business logic with data. I want to test that certain things get called depending on the response. 

         mockedThirdParty._performLogic().nestedLogic(null, () => {
           // Now resolve outer promise here with new data
           resolve({newdata: goodstuff});
           // Or depending on the logic, reject
        });
     });
   });
}

In my test for getStuff , I am mocking the response for getOtherStuff . I'm doing that like so:

Thing.prototype.getOtherStuff.mockImplementationOnce(()=> Promise.resolve({data: 'value'}));

So my whole test looks like this:

test('Here is my test name', async () => {
Thing.prototype.getOtherStuff.mockImplementationOnce(()=> Promise.resolve({data: 'value'}));

let instance = new Thing();

await instance.getStuff();

// We never get to this test because the test timeouts
expect(Thing.prototype._performLogic).toHaveBeenCalled()
});

So my test always timeout because I'm never resolving the outer promise in getStuff . I get this error:

Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:

How can I resolve this outer Promise while also mocking the inner async call getOtherStuff ?

EDIT -> See function above

How do I pass a callback to a mocked implementation of a third-party library?

I'm trying it like this, but I don't think I defining nestedLogic correctly:


   const mockedScene = {
      nestedLogic: jest.fn().mockImplementation(() => Promise.resolve())
   }

   jest
   .spyOn(Thirdparty.prototype, "_performLogic")
   .mockImplementation(() => (mockedScene))

The reason is you don't add a spy on _performLogic method.

You can use jest.spyOn(object, methodName) method to spy on the _performLogic method.

Eg

index.js :

function Thing() {}

Thing.prototype.getStuff = function() {
  return new Promise((resolve, reject) => {
    this.getOtherStuff().then(data => {
      this._performLogic();
      const goodstuff = data;
      resolve({ newdata: goodstuff });
    });
  });
};

Thing.prototype.getOtherStuff = function() {
  console.log("real get other stuff");
};

Thing.prototype._performLogic = function() {
  console.log("real perform logic");
};

module.exports = Thing;

index.spec.js :

const Thing = require(".");

describe("Thing", () => {
  describe("#getStuff", () => {
    afterEach(() => {
      jest.restoreAllMocks();
    });
    it("should pass", async () => {
      // make a stub
      jest
        .spyOn(Thing.prototype, "getOtherStuff")
        .mockImplementationOnce(() => Promise.resolve({ data: "value" }));
      // add a spy
      jest.spyOn(Thing.prototype, "_performLogic");
      let instance = new Thing();
      await instance.getStuff();
      expect(Thing.prototype._performLogic).toHaveBeenCalled();
      expect(Thing.prototype.getOtherStuff).toBeCalledTimes(1);
    });
  });
});

Unit test result with coverage report:

 PASS  src/stackoverflow/59148901/index.spec.js (7.573s)
  Thing
    #getStuff
      ✓ should pass (12ms)

  console.log src/stackoverflow/59148901/index.js:375
    real perform logic

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |    91.67 |      100 |    83.33 |    90.91 |                   |
 index.js |    91.67 |      100 |    83.33 |    90.91 |                14 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.013s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59148901

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM