Jest Mock函数未被调用 原函数逻辑执行问题排查
Jest Mock辅助函数不生效的问题原因及修复
核心问题原因
Mock逻辑不生效的根因是CommonJS模块的导入引用问题:你在主业务脚本中大概率是用解构的方式导入了helper.js的两个方法,导致测试中替换helper对象上的方法时,主脚本里持有的还是原始函数的引用,根本不会走到你写的Mock逻辑。
你当前主脚本的导入写法应该是这样的:
// 主脚本头部错误的导入写法 const { getAllModels, getItem } = require('./helper'); // 后续业务逻辑直接调用解构出来的函数 const { instance } = new SDK(id, authToken); const data = await getAllModels(instance); items = await getItem(instance, id);
这种写法在模块加载阶段就把helper导出的两个函数的引用拷贝到了主脚本的作用域变量里,后续你用jest.spyOn(helper, 'getAllModels')修改的只是helper模块对象上的属性指向,完全影响不到主脚本里已经存好的旧函数引用,运行时自然会执行原始逻辑。
两种修复方案
方案1:修改业务代码的导入与调用方式
不要提前解构导出的函数,导入整个helper模块,调用时从模块对象上取方法:// 主脚本头部改为导入整个helper模块 const helper = require('./helper'); // 调用时从helper对象上访问方法 const { instance } = new SDK(id, authToken); const data = await helper.getAllModels(instance); const items = await helper.getItem(instance, id);改完之后你原来写的
jest.spyOn逻辑就可以正常生效,因为调用时是实时从helper对象上读取方法,你替换成Mock实现后,调用拿到的就是自定义的Mock函数。方案2:不修改业务代码,用Jest原生模块Mock能力
如果你不想调整业务代码的写法,可以直接在测试文件中用jest.mock提前替换整个helper模块,无需手动写spyOn:// 测试文件顶部,在导入业务模块前声明模块Mock jest.mock('./helper', () => ({ getAllModels: jest.fn().mockResolvedValue('c'), getItem: jest.fn().mockResolvedValue('d') })); // 再导入业务模块和helper const helper = require('./helper'); const main = require('./你的主脚本路径'); test('主逻辑测试', async () => { // 你的测试instance和token逻辑 const baseVal = await main(instance, token); expect(baseVal).toBe("some value"); // 可选:断言Mock函数被正确调用 expect(helper.getAllModels).toHaveBeenCalledWith(instance); });注意Jest会自动把
jest.mock的逻辑提升到测试文件的最顶部执行,会在所有业务模块加载之前完成模块替换,主脚本加载时拿到的两个方法直接就是Mock函数,不会执行原始逻辑。
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

