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

