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

全局声明的jest.spyOn不执行原函数问题原因咨询

核心原因

这个问题和JS原型无关,是Jest的mock自动清理逻辑的执行时机导致的。

执行顺序说明

Jest测试文件的代码执行有固定顺序,同时默认开启了resetMocks配置:

  1. 首先执行测试文件全局作用域的所有代码:包含模块导入、全局变量声明、你写的全局jest.spyOn调用
  2. 对每个测试用例,Jest会先执行自动清理逻辑:把所有已创建的spy的实现重置为空函数、清空调用记录
  3. 再依次执行beforeEach钩子、测试用例内部代码

为什么全局声明的spy不会执行原函数

你在全局作用域创建spy时,spy默认确实会保留对原函数的引用、透传调用。但到测试用例真正执行前,Jest的自动清理逻辑已经把这个全局spy的实现重置成了空函数,自然不会执行原函数里的console.log。
而spy的调用记录能力还在,所以expect(spyObj).toHaveBeenCalled()的断言还是能通过。

为什么放在test内部/beforeEach就正常

这两个时机的代码执行,都在Jest单测的自动清理逻辑之后,此时新创建的spy还没被重置,会正常透传调用原函数,所以console.log会正常输出。

补充说明

如果你把Jest配置中的resetMocks设为false,全局声明的spy也能正常执行原函数,但非常不推荐这么做:会导致不同测试用例的spy/mock互相污染,测试结果不可靠。最佳实践是将spy的创建放在beforeEach或者单个测试用例内部,测试结束后可以手动调用spy.mockRestore()清理残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:30:01