如何在Jest测试中Mock setTimeout/延迟函数以跳过超长等待?
解决Jest测试中定时器等待过长的问题
一、Mock 原生 setTimeout,跳过实际等待时长
Jest内置定时器模拟能力,可直接跳过3小时等待,快速走完重试循环:
- 启用假定时器替代真实定时器
- 启动
main函数后,立即执行所有待处理的定时器任务 - 完成断言后恢复真实定时器,避免影响其他测试
修改后的测试代码:
it('unhappy case', async () => { let configFn = jest.fn(); let loggerFn = jest.fn(); jest.useFakeTimers(); const mainPromise = main(configFn, loggerFn); // 先启动函数,不等待 await jest.runAllTimersAsync(); // 快速执行所有定时器 await expect(mainPromise).rejects.toEqual(new Error('operation failed')); jest.useRealTimers(); // 恢复真实定时器 });
注:Jest 27及以上版本推荐用
jest.runAllTimersAsync()处理异步定时器;低版本可使用jest.runAllTimers(),配合await Promise.resolve()确保异步任务完成。
二、Mock 自定义 delay 函数
针对封装的delay函数,有两种Mock方式:
方式1:立即resolve(最快测试速度)
在测试文件顶部Mock整个delay模块,让delay直接完成:
jest.mock('./path/to/delay', () => ({ delay: jest.fn().mockResolvedValue(undefined), }));
方式2:模拟自定义等待时长
如果需要测试特定时长逻辑,可固定等待时间(比如1秒):
jest.mock('./path/to/delay', () => ({ delay: jest.fn(() => new Promise(resolve => setTimeout(resolve, 1000))), }));
若仍想使用Jest假定时器加速测试,可结合假定时器:
jest.mock('./path/to/delay', () => ({ delay: jest.fn().mockImplementation(() => new Promise(resolve => setTimeout(resolve, 0))), })); it('unhappy case with mocked delay', async () => { let configFn = jest.fn(); let loggerFn = jest.fn(); jest.useFakeTimers(); const mainPromise = main(configFn, loggerFn); await jest.runAllTimersAsync(); await expect(mainPromise).rejects.toEqual(new Error('operation failed')); jest.useRealTimers(); });
内容的提问来源于stack exchange,提问作者Username
相关产品推荐
相关产品推荐

