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.