You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:51:44