Jest模拟filter函数返回true后,如何让target函数返回'hi'?
问题分析与解决
核心问题
你遇到两个关键问题:
- 待测试代码逻辑错误:
target函数里,即便filter()返回true,也只是定义了一个箭头函数() => 'hi',既没有返回它,也没有执行它,所以target始终返回undefined。 - 模块内部函数引用问题:
target调用的是模块内部的filter变量,不是你导出的filter。因此你mock导出的filter不会影响target内部的调用逻辑。
解决方案
步骤1:修复target函数的逻辑
先把target改成能返回预期值的形式,比如:
const target = () => { if (filter()) return 'hi'; // 直接返回字符串,符合你期望的返回'hi' } const filter = () => false; module.exports = { target, filter }
如果你确实需要返回箭头函数,就改成return () => 'hi';,后续调用时再执行它即可。
步骤2:让target依赖可mock的filter(两种方式)
方式一:修改源码,让target调用导出的filter
调整源码,让target引用模块导出的filter,这样mock导出的版本就能生效:
const filter = () => false; const target = () => { // 调用导出的filter,而非本地变量 if (module.exports.filter()) return 'hi'; } module.exports = { target, filter }
对应的测试代码调整为(注意jest.mock要在require之前):
jest.mock('./index.js', () => { const o = jest.requireActual('./index.js'); return { ...o, filter: jest.fn(() => true) }; }); const index = require('./index'); test('test', () => { const x = index.target(); console.log(index.filter()); // true console.log(x); // 'hi' });
方式二:不修改源码,直接mock模块完整实现
如果你不想改动源码,可以在测试里重写整个模块的实现,让target里的filter指向mock函数:
jest.mock('./index.js', () => { const mockFilter = jest.fn(() => true); return { filter: mockFilter, target: () => { if (mockFilter()) return 'hi'; } }; }); const index = require('./index'); test('test', () => { const x = index.target(); console.log(index.filter()); // true console.log(x); // 'hi' });
内容的提问来源于stack exchange,提问作者mac
相关产品推荐
相关产品推荐

