组件测试中模拟定时器需启用 jest/vitest 的 fake timers(如 jest.usefaketimers()),手动推进时间(如 advancetimersbytime),并及时清理(userealtimers/clearalltimers),以避免真实等待、确保可预测性。

在组件测试中模拟定时器触发,核心是控制 setTimeout、setInterval 等原生定时器行为,避免真实等待、提升测试速度和可预测性。主流方案是使用 Jest 内置的 fake timers(伪定时器),配合 jest.useFakeTimers() 和手动推进时间。
启用并清理 fake timers
在测试前启用 fake timers,在测试后恢复真实定时器,防止干扰其他测试:
- 推荐在
beforeEach中调用jest.useFakeTimers() - 在
afterEach中调用jest.useRealTimers()清理 - 若使用
vi(Vitest),对应为vi.useFakeTimers()和vi.useRealTimers()
手动触发已注册的定时器
启用 fake timers 后,定时器不会自动执行。需显式触发:
-
jest.runAllTimers():立即执行所有已排队的定时器(包括重复的setInterval) -
jest.advanceTimersByTime(ms):将虚拟时钟向前拨动指定毫秒,只触发该时间段内到期的定时器 -
jest.runOnlyPendingTimers():仅执行当前已到期、尚未执行的定时器(适合单步验证)
结合 React 组件测试(以 React Testing Library 为例)
假设组件内部使用 useEffect 启动一个 2s 后更新状态的 setTimeout:
- 渲染组件后,调用
jest.advanceTimersByTime(2000) - 再使用
screen.getByText或expect(...).toBe...断言状态是否更新 - 注意:若组件使用
act更新状态,Jest fake timers 与act兼容良好,无需额外包裹
处理 setInterval 的循环场景
对轮询类逻辑(如每 1s 请求一次),需小心避免无限触发:
- 用
jest.advanceTimersByTime(1000)模拟一次间隔后检查副作用 - 用
jest.clearAllTimers()在断言后清除,防止后续测试受影响 - 若需验证多次循环,可连续调用
advanceTimersByTime或用runAllTimers(但要确保有退出条件)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











