这是我要测试的基本设置。
首先,我正在测试的方法:
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
});
});
});
}
在我对 getStuff
的测试中,我模拟了对 getOtherStuff
的响应。我是这样做的:
Thing.prototype.getOtherStuff.mockImplementationOnce(()=> Promise.resolve({data: 'value'}));
所以我的整个测试看起来像这样:
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()
});
所以我的测试总是超时,因为我从来没有解决 getStuff
中的外部 promise 。我收到此错误:
Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:
如何在模拟内部异步调用 getOtherStuff
的同时解决这个外部 Promise?
编辑 -> 查看上面的函数
如何将回调传递给第三方库的模拟实现?
我正在这样尝试,但我认为我没有正确定义 nestedLogic
:
const mockedScene = {
nestedLogic: jest.fn().mockImplementation(() => Promise.resolve())
}
jest
.spyOn(Thirdparty.prototype, "_performLogic")
.mockImplementation(() => (mockedScene))
最佳答案
原因是您没有在 _performLogic
方法上添加 spy 。
您可以使用 jest.spyOn(object, methodName)方法来监视 _performLogic
方法。
例如
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);
});
});
});
带有覆盖率报告的单元测试结果:
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
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59148901
关于javascript - 如何使用 Jest 解决模拟函数内的外部 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59148901/