You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jest结合useFakeTimers测试含setTimeout的异步函数?

解决Jest虚拟时间测试异步休眠函数的问题

你的测试超时是因为调用await systemUnderTest()时,fake timers会阻塞setTimeout的执行,导致Promise一直处于pending状态,测试自然会超时。正确的做法是先触发函数执行,再运行虚拟定时器,最后等待函数完成,具体实现如下:

正确测试代码

test('myTest', async () => {
  jest.useFakeTimers();
  // 启动函数但不立即等待,此时函数执行到await处暂停
  const promise = systemUnderTest();
  // 运行所有虚拟定时器,触发setTimeout回调使Promise resolve
  jest.runAllTimers();
  // 等待函数执行完成
  await promise;
  jest.useRealTimers();
});

原理说明

  • 先调用systemUnderTest()但不await,函数会打印"One",随后遇到await new Promise(...)暂停执行,此时Promise处于pending状态。
  • 调用jest.runAllTimers()会立即执行所有被fake timers拦截的定时器回调,触发setTimeout的resolve函数,让之前的Promise变为resolved状态,函数继续执行并打印"Two"。
  • 最后await promise等待整个函数执行完成,确保测试流程正常结束。

可选优化:精准执行单个定时器

如果你的函数包含多个定时器,只想执行当前pending的1秒休眠定时器,可以用jest.runOnlyPendingTimers()替代jest.runAllTimers(),避免意外执行其他未预期的定时器:

test('myTest', async () => {
  jest.useFakeTimers();
  const promise = systemUnderTest();
  jest.runOnlyPendingTimers();
  await promise;
  jest.useRealTimers();
});

内容的提问来源于stack exchange,提问作者carlo.milanesi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:07:46