我正在尝试模拟console.info
,我知道它将在导入的函数运行时被调用。该功能完全由单个fetch
组成,当不在生产环境中运行时,它使用console.info
报告请求和响应。
在问题Jest. How to mock console when it is used by a third-party-library?上,评分最高的答案建议覆盖global.console
,因此我正在使用jest.spyOn
进行尝试:
import * as ourModule from "../src/ourModule";
test("Thing", () => {
// Tested function requires this. Including it here in case it's causing
// something quirky that readers of this question may know about
global.fetch = require("jest-fetch-mock");
const mockInfo = jest.spyOn(global.console, "info").mockImplementation(
() => { console.error("mockInfo") }
);
ourModule.functionBeingTested("test");
expect(mockInfo).toHaveBeenCalled();
}
按预期,输出包含“ mockInfo”的实例。但是,然后使用toHaveBeenCalled()
进行测试失败。
expect(jest.fn()).toHaveBeenCalled()
Expected mock function to have been called, but it was not called.
40 |
41 | ourModule.functionBeingTested("test");
> 42 | expect(mockInfo).toHaveBeenCalled();
| ^
43 |
at Object.toHaveBeenCalled (__tests__/basic.test.js:42:22)
console.error __tests__/basic.test.js:38
mockInfo
我已经尝试将spyOn
移至模块加载之前的位置,如答案中的注释之一所示,结果没有差异。我在这里想念什么?
这是有问题的功能:
function functionBeingTested(value) {
const fetchData = {
something: value
};
fetch("https://example.com/api", {
method: "POST",
mode: "cors",
body: JSON.stringify(fetchData),
})
.then( response => {
if (response.ok) {
if (MODE != "production") {
console.info(fetchData);
console.info(response);
}
} else {
console.error(`${response.status}: ${response.statusText}`);
}
})
.catch( error => {
console.error(error);
});
}
答案 0 :(得分:1)
console.info
在Promise回调中被调用,该回调在ourModule.functionBeingTested
返回并运行expect
时尚未执行。
在运行console.info
之前,请确保已运行调用expect
的Promise回调。
最简单的方法是从Promise
返回ourModule.functionBeingTested
:
function functionBeingTested(value) {
const fetchData = {
something: value
};
return fetch("https://example.com/api", { // return the Promise
method: "POST",
mode: "cors",
body: JSON.stringify(fetchData),
})
.then(response => {
if (response.ok) {
if (MODE != "production") {
console.info(fetchData);
console.info(response);
}
} else {
console.error(`${response.status}: ${response.statusText}`);
}
})
.catch(error => {
console.error(error);
});
}
...并在断言之前等待其解决:
test("Thing", async () => { // use an async test function...
// Tested function requires this. Including it here in case it's causing
// something quirky that readers of this question may know about
global.fetch = require("jest-fetch-mock");
const mockInfo = jest.spyOn(global.console, "info").mockImplementation(
() => { console.error("mockInfo") }
);
await ourModule.functionBeingTested("test"); // ...and wait for the Promise to resolve
expect(mockInfo).toHaveBeenCalled(); // SUCCESS
});