Reputation: 1211
Here is the function I am trying to test:
index.js
:
import ThirdParty from 'third-party';
function Main(){}
Main.prototype.getStuff = function(){
return new Promise((resolve, reject) => {
this.getOtherStuff().then((data) => {
// Business logic...
const tpinstance = new ThirdParty();
tpinstance.createThing().nestedFunction(null, () => {
// This is where I'm resolving the outer function
resolve({newdata: goodstuff});
});
});
}
}
Main.prototype.getOtherStuff = function(){
return new Promise((resolve, reject) => {
resolve();
})
}
I am failing to resolve the the promise from the outer most function so I'm getting this error:
Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:
My Test
//index.spec.js
import ThirdParty from 'third-party';
jest.mock('third-party');
describe('Main', () => {
describe('#getStuff', () => {
test('Want this to pass', async () => {
jest
.spyOn(Main.prototype, "getOtherStuff")
.mockImplementationOnce(() => Promise.resolve({ data: "value" }));
const mockedThing = {
// This implementation seems wrong to me.
nestedFunction: jest.fn().mockImplementation(() => Promise.resolve())
}
jest
.spyOn(ThirdParty.prototype, "createThing")
.mockImplementation(() => (mockedThing))
let instance = new Main();
await instance.getStuff();
//assertions -> I never get here cause it timesout
expect(Main.prototype.getOtherStuff).toHaveBeenCalled();
});
});
});
How can I mock out nestedFunction
in a way where I'll be resolving the outer function in a callback I pass to nestedFunction
?
Upvotes: 1
Views: 1385
Reputation: 102437
Here is the unit test solution:
index.js
:
import ThirdParty from "./third-party";
export default function Main() {}
Main.prototype.getStuff = function() {
return new Promise((resolve, reject) => {
this.getOtherStuff().then(data => {
const tpinstance = new ThirdParty();
tpinstance.createThing().nestedFunction(null, () => {
const goodstuff = data;
resolve({ newdata: goodstuff });
});
});
});
};
Main.prototype.getOtherStuff = function() {
return new Promise((resolve, reject) => {
resolve();
});
};
third-party.js
:
export default function ThirdParty() {}
ThirdParty.prototype.createThing = function() {
console.log("real create thing");
return this;
};
ThirdParty.prototype.nestedFunction = function(arg, cb) {
console.log("real nested function");
};
index.spec.js
:
import Main from "./";
import ThirdParty from "./third-party";
jest.mock("./third-party.js", () => {
const mThirdParth = {
createThing: jest.fn().mockReturnThis(),
nestedFunction: jest.fn()
};
return jest.fn(() => mThirdParth);
});
describe("Main", () => {
describe("#getStuff", () => {
afterEach(() => {
jest.restoreAllMocks();
jest.resetAllMocks();
});
it("should pass", async () => {
jest
.spyOn(Main.prototype, "getOtherStuff")
.mockResolvedValueOnce({ data: "value" });
let callback;
const tpinstance = new ThirdParty();
tpinstance.createThing().nestedFunction.mockImplementation((arg, cb) => {
callback = cb;
cb();
});
const instance = new Main();
const pending = instance.getStuff();
console.log(pending);
const actual = await pending;
expect(actual).toEqual({ newdata: { data: "value" } });
expect(Main.prototype.getOtherStuff).toBeCalledTimes(1);
expect(tpinstance.createThing).toHaveBeenCalled();
expect(tpinstance.createThing().nestedFunction).toBeCalledWith(
null,
callback
);
});
});
});
Unit test result with coverage report:
PASS src/stackoverflow/59150545/index.spec.js
Main
#getStuff
✓ should pass (12ms)
console.log src/stackoverflow/59150545/index.spec.js:31
Promise { <pending> }
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 84.62 | 100 | 71.43 | 83.33 | |
index.js | 84.62 | 100 | 71.43 | 83.33 | 18,19 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.529s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59150545
Upvotes: 2