如何清除Jest中jest.fn()创建的mock函数上的spy监听?
如何清除Jest中mock函数上的spy
问题描述:如果原始函数不是jest.fn(),使用jest.restoreAllMocks()可以正常生效,但如果是jest.fn()创建的函数,要如何正确清除其上的所有spy呢?
现有测试代码如下:
describe('Mock', () => { const mock = { method1: jest.fn().mockReturnValue(false), }; afterEach(() => { // 以下方法都无法清除spy jest.clearAllMocks(); jest.resetAllMocks(); jest.restoreAllMocks(); }); it('默认返回false', () => { expect(mock.method1()).toEqual(false); }); it('应用spy实现后修改返回值为true', () => { jest.spyOn(mock, 'method1').mockReturnValue(true); expect(mock.method1()).toEqual(true); }); // 该测试用例执行失败 it('每次测试后重置为原始返回值', () => { expect(mock.method1()).toEqual(false); }); });
原因说明
原有三个方法失效的核心逻辑如下:
jest.clearAllMocks():仅清除mock函数的调用记录、传参、返回值历史,不会修改mock的实现逻辑jest.resetAllMocks():会将mock函数的实现重置为返回undefined的空函数,不会回到你初始定义的返回false的实现jest.restoreAllMocks():默认配置下仅能恢复通过jest.spyOn包装的非mock原始函数,且需要开启全局配置restoreMocks: true才会自动生效,对本身就是jest.fn()创建的mock函数默认不处理
推荐解决方案
方案1:每次测试前重新初始化mock(最稳妥,无状态污染)
将mock对象的初始化逻辑放到beforeEach中,保证每次测试运行时拿到的都是初始状态的mock:
describe('Mock', () => { let mock; // 每次测试前重新创建mock,自然携带初始实现 beforeEach(() => { mock = { method1: jest.fn().mockReturnValue(false), }; }); it('默认返回false', () => { expect(mock.method1()).toEqual(false); }); it('应用spy实现后修改返回值为true', () => { jest.spyOn(mock, 'method1').mockReturnValue(true); expect(mock.method1()).toEqual(true); }); it('每次测试后重置为原始返回值', () => { expect(mock.method1()).toEqual(false); }); });
方案2:手动重置mock实现
如果需要复用顶层定义的mock,可以提前保存初始实现,在afterEach中手动恢复:
describe('Mock', () => { // 保存初始实现 const originalMethod1 = jest.fn().mockReturnValue(false); const mock = { method1: originalMethod1, }; afterEach(() => { // 每次测试后恢复初始实现 mock.method1.mockImplementation(originalMethod1); }); it('默认返回false', () => { expect(mock.method1()).toEqual(false); }); it('应用spy实现后修改返回值为true', () => { jest.spyOn(mock, 'method1').mockReturnValue(true); expect(mock.method1()).toEqual(true); }); it('每次测试后重置为原始返回值', () => { expect(mock.method1()).toEqual(false); }); });
方案3:开启restoreMocks配置
在jest配置文件(jest.config.js、jest.config.ts等)中添加restoreMocks: true,开启后jest.restoreAllMocks()会自动将所有jest.spyOn创建的spy恢复到spy执行前的实现,无需额外手动处理:
// jest.config.js module.exports = { // 其他配置 restoreMocks: true }
开启后原测试代码中的jest.restoreAllMocks()即可正常生效。
内容的提问来源于stack exchange,提问作者Michał Terczyński SM
相关产品推荐
相关产品推荐

