Jest 提供内置定时器模拟功能以加速异步测试;需显式调用 jest.useFakeTimers() 启用,配合 beforeEach/afterEach 隔离,并用 advanceTimersByTime 或 runAllTimers 控制执行,辅以 expect 断言和 getTimerCount 验证,最后用 useRealTimers 恢复。

Jest 提供了内置的定时器模拟功能,可以让你在测试异步代码时“快进”时间,避免真实等待,大幅提升测试速度和稳定性。
启用 Jest 的定时器模拟
默认情况下,Jest 不会自动模拟 setTimeout、setInterval 等全局定时器。你需要显式启用:
- 在测试文件顶部调用
jest.useFakeTimers() - 推荐搭配
beforeEach和afterEach使用,确保每个测试隔离:
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
用 jest.advanceTimersByTime() 快进指定毫秒
这是最常用的快进方式,让所有已设定但未触发的定时器向前推进指定时间(单位:毫秒):
- 例如:延迟 1000ms 的
setTimeout,调用jest.advanceTimersByTime(1000)后立即执行回调 - 注意:它只推进“已存在”的定时器,不会触发未来新创建的定时器(除非再次 advance)
- 支持多次调用,适合多阶段延时逻辑
用 jest.runAllTimers() 立即执行所有待处理定时器
适用于你希望“清空队列”,不管延迟多久,全部立刻触发:
立即学习“Java免费学习笔记(深入)”;
- 常用于测试反复调用
setInterval或递归setTimeout的场景 - ⚠️ 谨慎使用:如果定时器内部又设置了新定时器(如轮询),可能引发无限循环,建议配合
jest.runOnlyPendingTimers()
验证定时器是否按预期设置
除了快进,还可以断言定时器行为本身是否正确:
-
expect(setTimeout).toHaveBeenCalledTimes(1)—— 检查是否调用了setTimeout -
expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 3000)—— 检查最后一次调用的参数 -
jest.getTimerCount()—— 获取当前待执行定时器数量,辅助判断逻辑是否遗漏清理
不复杂但容易忽略的是:记得在测试后恢复真实定时器,否则可能影响后续测试或报错。用 jest.useRealTimers() 收尾是稳妥做法。


















