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

Jest中层叠定时器与异步函数测试:cb未触发如何修复?

Jest异步定时器测试问题

场景复现

第一段测试代码中,jest.runAllTimers()能模拟足够时间流逝,cb()可以正常触发:

test('test', async () => {
  jest.useFakeTimers();

  const cb = jest.fn();
  const func = jest.fn().mockResolvedValueOnce(1);

  setTimeout(async () => {
    setTimeout(() => {
      cb();
    }, 1000);
  }, 1000);

  jest.runAllTimers();
});

但在下面的测试代码中,因为加入了await func()的异步逻辑,cb()从未被触发,测试无法通过:

test('test', async () => {
  jest.useFakeTimers();

  const cb = jest.fn();
  const func = jest.fn().mockResolvedValueOnce(1);

  setTimeout(async () => {
    await func();
    setTimeout(() => {
      cb();
    }, 1000);
  }, 1000);

  jest.runAllTimers();

  expect(cb).toHaveBeenCalledTimes(1);
});

问题原因

当setTimeout的回调是异步函数时,jest.runAllTimers()会同步执行这个回调,但遇到await时,函数会暂停并返回一个Promise。此时Jest的定时器模拟不会等待这个Promise完成,后续的内部setTimeout还没来得及被注册到定时器队列中,所以第一次runAllTimers()执行完后,没有待处理的定时器去触发cb。

解决方案

方法一:两次调用runAllTimers并等待微任务

test('test', async () => {
  jest.useFakeTimers();

  const cb = jest.fn();
  const func = jest.fn().mockResolvedValueOnce(1);

  setTimeout(async () => {
    await func();
    setTimeout(() => {
      cb();
    }, 1000);
  }, 1000);

  // 第一次执行外层setTimeout的回调
  jest.runAllTimers();
  // 等待微任务队列执行完毕,确保await func()完成,内部setTimeout被注册
  await Promise.resolve();
  // 第二次执行所有已注册的定时器,触发cb
  jest.runAllTimers();

  expect(cb).toHaveBeenCalledTimes(1);
});

方法二:分步推进时间并等待微任务

这种方式更精准地控制时间推进的节点:

test('test', async () => {
  jest.useFakeTimers();

  const cb = jest.fn();
  const func = jest.fn().mockResolvedValueOnce(1);

  setTimeout(async () => {
    await func();
    setTimeout(() => {
      cb();
    }, 1000);
  }, 1000);

  // 推进1000ms,触发外层setTimeout的回调
  jest.advanceTimersByTime(1000);
  // 等待await的Promise完成,让内部setTimeout被注册
  await Promise.resolve();
  // 再推进1000ms,触发内部setTimeout的回调,执行cb
  jest.advanceTimersByTime(1000);

  expect(cb).toHaveBeenCalledTimes(1);
});

两种方法的核心都是:等待异步回调中的微任务完成,确保内部的定时器被注册后,再执行定时器模拟逻辑。

内容的提问来源于stack exchange,提问作者Emre Tapcı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:45:23