jest 的 fake timers 是 mock 定时器的推荐方式,通过 jest.usefaketimers() 启用、jest.advancetimersbytime() 推进时间、jest.userealtimers() 还原,确保测试高效可控。

在 JavaScript 单元测试中 Mock 定时器函数(setTimeout、setInterval、clearTimeout、clearInterval)主要是为了控制异步行为、避免真实等待、提升测试速度和确定性。Jest 提供了开箱即用的 fake timers 支持,是最常用也最推荐的方式。
使用 Jest 的 fake timers(推荐)
Jest 内置了对定时器的模拟能力,无需手动重写全局方法,且能精确控制时间推进。
- 启用 fake timers:在测试文件顶部或
beforeEach中调用jest.useFakeTimers() - 触发定时器:用
jest.runAllTimers()立即执行所有待处理定时器;或用jest.advanceTimersByTime(ms)推进指定毫秒数 - 清理还原:测试结束后建议调用
jest.useRealTimers(),避免影响其他测试
示例:
test('should call callback after 100ms', () => {
jest.useFakeTimers();
const callback = jest.fn();
setTimeout(callback, 100);
expect(callback).not.toHaveBeenCalled();
jest.advanceTimersByTime(100);
expect(callback).toHaveBeenCalledTimes(1);
jest.useRealTimers(); // 还原
});
手动 Mock 全局定时器(不推荐,仅作了解)
虽然可以手动覆盖 global.setTimeout 等,但容易出错、难以还原、无法自动管理清除逻辑,一般只在非 Jest 环境(如 Mocha + Sinon)中考虑。
- 保存原始引用再替换,避免污染全局环境
- 需自行实现队列管理、清除逻辑(如记录所有
setTimeoutID 并支持clearTimeout) - 无法自动同步
Date.now(),可能造成时间判断失准
不建议在 Jest 中这么做——fake timers 已足够健壮且语义清晰。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
注意 clearInterval / clearTimeout 的行为一致性
启用 fake timers 后,clearTimeout 和 clearInterval 依然有效,且 Jest 会正确识别已清除的定时器不会被执行。
- 调用
clearTimeout(id)后,即使再runAllTimers,该回调也不会触发 - 可配合
jest.getTimerCount()检查当前挂起的定时器数量,辅助验证是否被正确清除
例如:
test('should not call callback if cleared', () => {
jest.useFakeTimers();
const callback = jest.fn();
const id = setTimeout(callback, 100);
clearTimeout(id);
jest.runAllTimers();
expect(callback).not.toHaveBeenCalled();
jest.useRealTimers();
});
在 beforeEach/afterEach 中统一管理
为避免每个测试都手动开关 fake timers,可在测试套件顶层统一配置:
describe('Timer-dependent logic', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
test('...', () => {
// 直接使用 advanceTimersByTime 等,无需重复 setup
});
});
这样既保证隔离性,又减少样板代码。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










