如何在Jasmine 2中监视模块导出的函数?
解决模块导入函数的监视问题
我来帮你搞定这个问题——你之所以没法用spyOn监视lookupFooFunction并断言调用参数,核心原因是这个函数是通过模块导入的独立函数,不是挂载在window或某个对象上的方法,而spyOn(不管是Jest还是Jasmine的实现)都只能监视对象的属性方法,直接对独立函数使用肯定会报错。
先看你的代码细节:
- 源代码里,
lookupFooFunction是从../../utils/sampleJSFile导入的,在a()里直接调用 - 测试代码里你错误地尝试监视
window上的同名函数,这和实际代码里的函数根本不是同一个引用,所以既监视不到调用,还会触发报错
解决方案(以Jest为例,Jasmine思路一致)
方法1:模拟整个工具模块
最简单的方式是直接模拟整个sampleJSFile模块,把lookupFooFunction替换成一个mock函数:
// 模拟整个工具模块,将lookupFooFunction替换为jest mock函数 jest.mock('../../utils/sampleJSFile', () => ({ __esModule: true, // ES模块必须加这个标识 default: jest.fn() })); // 导入被模拟的函数 import lookupFooFunction from '../../utils/sampleJSFile'; // 导入包含a()的视图/组件模块(替换成你实际的模块路径) import { a } from './your-target-module'; test('调用a()时会传入正确参数调用lookupFooFunction', () => { // 执行目标函数 a(); // 断言调用情况 expect(lookupFooFunction).toHaveBeenCalledWith('bla', 'zoo'); });
方法2:单独监视目标函数
如果不想模拟整个模块,只想监视lookupFooFunction这一个函数,可以用jest.spyOn替换模块导出的函数:
// 先导入整个工具模块 import * as sampleJSModule from '../../utils/sampleJSFile'; // 导入包含a()的目标模块 import { a } from './your-target-module'; test('a()会传入正确参数调用lookupFooFunction', () => { // 监视模块中的lookupFooFunction,替换为mock函数 const spy = jest.spyOn(sampleJSModule, 'default').mockImplementation(() => {}); // 执行目标函数 a(); // 断言调用参数 expect(spy).toHaveBeenCalledWith('bla', 'zoo'); // 测试结束后恢复原函数(可选,避免影响其他测试用例) spy.mockRestore(); });
关键注意事项
- 确保测试里的模块导入路径和源代码里的完全一致,否则mock不会生效
- 如果用的是Jasmine而非Jest,思路类似:你需要把导入的函数挂载到一个可访问的对象上,或者用
spyOn(require('../../utils/sampleJSFile'), 'default')(针对CommonJS模块) - 不要再尝试监视
window上的函数了,除非你的源代码确实把lookupFooFunction挂载到了window上(显然你的代码里没这么做)
内容的提问来源于stack exchange,提问作者Gwater17
相关产品推荐
相关产品推荐

