使用jest.spyOn无法正确模拟默认导出函数的问题排查
Jest Spy无法Mock内部函数调用的问题解决
问题根源
你的测试用例失败的核心原因是:getUsers函数内部直接调用的是模块内定义的原始getJack函数,而不是你导出对象上的getJack方法。
当你用jest.spyOn(users, 'getJack')创建间谍时,只是修改了导出对象上的getJack引用,但模块内部的getJack变量依然指向原始函数,所以getUsers执行时还是会返回原始的'Jack',导致断言失败。
解决方案
这里提供三种可行的修改方式:
方案1:让内部函数引用导出对象上的方法
修改esm-user.js,让getUsers调用导出对象上的getJack:
// esm-user.js const getJack = () => 'Jack'; const getJill = () => 'Jill'; const exports = { getJack, getJill, getUsers: () => [exports.getJack(), exports.getJill()] }; export default exports;
这样getUsers会始终引用导出对象上的getJack,当Spy修改这个引用时,就能生效。
方案2:统一使用对象内的方法调用
把所有函数都挂载到同一个对象上,内部直接调用对象的方法:
// esm-user.js const users = { getJack: () => 'Jack', getJill: () => 'Jill', getUsers: () => [users.getJack(), users.getJill()] }; export default users;
这种写法更直观,getUsers直接调用users对象的getJack,Spy修改对象属性后会直接影响内部调用。
方案3:使用Jest模块Mock
在测试文件中通过jest.mock直接mock模块的导出,替换getJack的实现:
// esm-user-spy.spec.js import users from './esm-user'; // 保留模块其他原始实现,仅mock getJack jest.mock('./esm-user', () => { const original = jest.requireActual('./esm-user'); return { ...original, getJack: jest.fn(() => 'Mock Jack') }; }); describe("Mocks and Spies", () => { test.only("partial mock (jack)", () => { expect(users.getUsers()).toEqual(['Mock Jack', 'Jill']); }); });
这种方式不需要修改源文件,直接在测试层替换模块导出的函数实现。
内容的提问来源于stack exchange,提问作者RoyM
相关产品推荐
相关产品推荐

