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

Jest监听全局函数时,被其他函数调用为何失效?

问题原因与解决方案

核心原因

在非模块化的全局代码环境中,main函数内部调用的spyOnMe是词法作用域内的直接引用,而非从window对象上查找的属性。

当你执行jest.spyOn(window, 'spyOnMe').mockReturnValue(mockedValue)时,仅修改了window.spyOnMe这个全局属性的指向,但main函数在定义时已经捕获了原始spyOnMe函数的引用——这个引用不会因为window上的属性被修改而改变。

直接调用spyOnMe()能拿到模拟值,是因为测试文件作用域中,spyOnMe默认指向window.spyOnMe(全局变量自动挂载到window),但main内部的调用始终使用定义时的原始函数引用。

解决方案

方案1:修改源码(推荐,符合全局环境规范)

调整main函数,明确从window调用spyOnMe,让后续修改window.spyOnMe能直接影响main的执行:

// ./src/index.js
function spyOnMe() {
  return "Hello World!";
}

function main() {
  const text = window.spyOnMe(); // 改为从window对象调用
  return text;
}

方案2:在测试环境中替换原始函数引用

如果无法修改源码,可在自定义testEnvironment预加载代码时,让main内部的函数引用指向window上的版本,或直接覆盖全局作用域的函数:

// ./src/index.spec.js
it('should spyOn spyOnMe', () => {
  const mockedValue = 'Thanks for helping!';
  // 直接替换全局作用域中的spyOnMe函数
  global.spyOnMe = jest.fn().mockReturnValue(mockedValue);
  
  expect(spyOnMe()).toBe(mockedValue);
  const result = main();
  expect(result).toBe(mockedValue);
});

或者在自定义jest.env.js预加载时,将函数直接挂载为window属性,并让内部调用依赖这些属性:

// jest.env.js 预加载逻辑
window.spyOnMe = function spyOnMe() {
  return "Hello World!";
};

window.main = function main() {
  const text = window.spyOnMe();
  return text;
};

内容的提问来源于stack exchange,提问作者Gpack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 08:40:48