考虑代码-
// utils.js
export const foo = async (a, b) => {
// do something
bar(a)
}
export const bar = async (a) => {
// do something
}
// utils.spec.js
const utils = require('./utils');
const barSpy = jest.spyOn(utils, 'bar');
const result = await utils.foo('a', 'b');
expect(barSpy).toHaveBeenCalledTimes(1);
测试失败-
Error: expect(jest.fn()).toHaveBeenCalledTimes(expected)
Expected number of calls: 1
Received number of calls: 0
我阅读了https://medium.com/@DavideRama/mock-spy-exported-functions-within-a-single-module-in-jest-cdf2b61af642和https://github.com/facebook/jest/issues/936,但无法通过多个排列解决。
您对此有任何疑问吗?
答案 0 :(得分:2)
如您共享的article中所述,在utils.js
文件中,您正在导出具有foo
和bar
的对象。您的utils.spec.js
实际上导入了exports.foo
和exports.bar
。因此,您嘲笑exports.bar
通过如下更改utils.js
,当您模拟bar时,您将模拟foo使用的实际bar。
utils.js
const bar = async () => {};
const foo = async () => {
exportFunctions.bar();
};
const exportFunctions = {
foo,
bar
};
module.exports = exportFunctions;
在此codesandbox中实际操作。您可以打开一个新终端(右下角),然后在浏览器中直接运行npm test
答案 1 :(得分:1)
正如@ bhargav-shah所说,当您开玩笑地监视模块函数时,实际上是在监视其导出的函数值,而不是内部函数本身。
发生这种情况是因为commonJS模块是如何工作的。使用ES模块环境,实际上您可以在不修改代码的情况下实现您要在此处执行的操作,因为导出将是绑定。 here可以找到更深入的解释。
目前Jest不支持ES模块,因此使代码工作的唯一方法是从foo
函数中调用实际导出的函数:
// utils.js
export const foo = async (a, b) => {
// do something
// Call the actual exported function
exports.bar(a)
}
export const bar = async (a) => {
// do something
}
// utils.spec.js
const utils = require('./utils');
const barSpy = jest.spyOn(utils, 'bar');
const result = await utils.foo('a', 'b');
expect(barSpy).toHaveBeenCalledTimes(1);