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

Jest中resetAllMocks等四个方法的区别与示例解析

我太懂这种纠结了!Jest这几个带reset/restore的方法命名简直像孪生兄弟,刚上手的时候我也经常搞混。别急,我给你逐个拆解,配上实打实的代码例子,帮你把它们的差异掰得明明白白。

1. resetAllMocks():清空mock的「调用状态」,保留mock实现

这个方法的核心是只重置mock的调用记录、调用参数、实例数量这些状态数据,完全不会改变你给mock设置的自定义实现。比如你给mock设了mockReturnValue或者mockImplementation,重置后这些逻辑依然生效,只是之前的调用痕迹被清掉了。

代码示例

// 被测试的工具模块 utils.js
export const getUser = () => ({ id: 1 });

// 测试文件 utils.test.js
import { getUser } from './utils';

// 先mock整个utils模块
jest.mock('./utils');

test('第一次调用mock', () => {
  // 给mock设置自定义返回值
  getUser.mockReturnValue({ id: 99 });
  expect(getUser()).toEqual({ id: 99 });
  // 此时调用次数是1
  expect(getUser).toHaveBeenCalledTimes(1);
});

test('调用resetAllMocks之后', () => {
  // 清空所有mock的调用状态
  jest.resetAllMocks();
  
  // 👉 重点:mock的实现没丢,还是返回{ id: 99 }
  expect(getUser()).toEqual({ id: 99 });
  // 之前的调用记录被清空了,这次是当前测试的第1次调用
  expect(getUser).toHaveBeenCalledTimes(1);
});

适用场景

当你在多个测试用例里复用同一个mock逻辑,但需要确保每个测试的调用记录是独立的,不会被之前的测试用例干扰时,用它就对了。


2. restoreAllMocks():把mock恢复成「原始函数」,同时清空状态

这个方法是专门针对用jest.spyOn()创建的mock的——它会把被spy替换的函数完全恢复成原始实现,同时也会清空它的调用状态(相当于resetAllMocks() + 恢复原函数)。注意:如果是用jest.mock()直接mock整个模块的,这个方法无效,除非你在mock时特意保留了原始实现。

代码示例

test('用spyOn临时替换函数,之后恢复', () => {
  // 用spyOn替换console.log,让它啥也不输出
  const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
  
  console.log('这条日志不会输出');
  expect(logSpy).toHaveBeenCalledTimes(1);
  
  // 恢复所有被spyOn的mock到原始状态
  jest.restoreAllMocks();
  
  // 👉 现在console.log变回了原始函数,会正常输出
  console.log('这条日志会正常打印在控制台');
  // 因为已经恢复成原始函数,之前的spy引用不再跟踪调用了
  expect(logSpy).not.toHaveBeenCalled();
});

适用场景

当你只是临时替换某个内置函数或者第三方函数来测试,测试完成后需要把它恢复原状,避免影响其他测试用例或者全局环境时,就用这个方法。


3. resetModules() & resetModuleRegistry():清空模块缓存,重新加载模块

先划重点:这俩是完全一样的东西,resetModuleRegistry()就是resetModules()的别名,功能没有任何区别。

它的作用是清空Jest的模块缓存,让你下次用require或者import导入模块时,Jest会重新加载模块文件,而不是用之前缓存的版本。这意味着你可以在测试过程中切换模块的mock状态和原始状态。

代码示例

// 被测试的配置模块 config.js
export const getEnv = () => 'production';

// 测试文件 config.test.js
test('mock模块后,重置缓存再获取原始模块', async () => {
  // 先mock整个config模块
  jest.mock('./config', () => ({ getEnv: jest.fn().mockReturnValue('test') }));
  const { getEnv } = require('./config');
  expect(getEnv()).toBe('test');
  
  // 清空模块缓存
  jest.resetModules();
  
  // 👉 重新导入,此时mock已经失效,拿到的是原始模块
  const originalConfig = require('./config');
  expect(originalConfig.getEnv()).toBe('production');
});

适用场景

当你需要在不同测试用例中对同一个模块应用不同的mock,或者在单个测试用例中需要切换模块的mock和原始状态时,这个方法就派上用场了。


最后再给你做个差异总结表,方便快速区分

方法作用对象核心效果典型场景
resetAllMocks()所有mock函数清空调用记录/参数,保留mock实现复用mock逻辑,隔离测试间的调用痕迹
restoreAllMocks()jest.spyOn()创建的mock恢复原始函数,同时清空状态临时替换函数后,恢复原状避免污染环境
resetModules()/resetModuleRegistry()模块缓存清空缓存,重新加载模块切换模块的mock/原始状态,不同测试用例用不同模块版本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:09:30