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

使用modern模式useFakeTimers时异步测试超时问题求助

React Native中Jest现代计时器异步测试超时问题

问题描述

此前了解过关于legacy计时器结合异步回调的相关讨论,但在React Native项目中使用Jest的modern计时器时遇到了超时问题。无论在beforeAll、beforeEach钩子还是异步测试用例内部启用jest.useFakeTimers("modern")(Jest 26版本)或jest.useFakeTimers()(Jest 29版本),只要在异步测试中启用fake timers,就会触发超时错误。

Jest配置

当前项目的Jest配置如下:

"jest": {
  "preset": "react-native",
  "modulePathIgnorePatterns": [
    "<rootDir>/example/node_modules",
    "<rootDir>/lib/"
  ]
}

错误信息

测试时抛出的超时错误:

Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.

环境情况

  • 初始使用Expo SDK 47对应的Jest 26.6.3
  • 升级至jest@29.3.1后问题仍未解决
  • 已提交相关Bug报告

可行解决方法

1. 手动触发微任务队列

现代计时器模式下,Jest不会自动处理微任务(比如Promise回调),因此在推进计时器后需要手动触发微任务执行:

test('带计时器的异步测试', async () => {
  jest.useFakeTimers('modern');
  
  // 执行包含定时器的异步函数
  const asyncTask = yourAsyncFunctionWithTimer();
  
  // 推进所有计时器
  jest.runAllTimers();
  // 触发微任务队列,处理Promise回调
  await Promise.resolve();
  
  // 等待异步任务完成并断言
  const result = await asyncTask;
  expect(result).toBe(/* 预期结果 */);
  
  // 恢复真实计时器
  jest.useRealTimers();
});

也可以使用jest.runAllTicks()替代await Promise.resolve(),效果一致。

2. 隔离单个测试的计时器状态

避免在全局钩子中启用fake timers,改为在每个测试用例内部单独启用和销毁,确保测试环境的独立性:

test('独立测试用例', async () => {
  jest.useFakeTimers('modern');
  
  // 测试逻辑:触发包含定时器的操作
  triggerTimerAction();
  
  // 推进计时器并处理微任务
  jest.runAllTimers();
  await jest.runAllTicks();
  
  // 执行断言
  expect(someState).toBe(true);
  
  // 清理计时器
  jest.useRealTimers();
});

3. 临时调整测试超时时间

如果上述方法无法立即生效,可以临时延长单个测试的超时时间,避免因微任务处理延迟导致的超时:

test('超时敏感的异步测试', async () => {
  // 测试逻辑
}, 10000); // 将超时时间设置为10秒

注意:这只是临时缓解方案,建议优先修复计时器和微任务的触发逻辑。

4. 检查残留定时器

确保在每个测试结束后清理所有fake timers,避免残留的定时器影响后续测试:

afterEach(() => {
  jest.useRealTimers();
  jest.clearAllTimers();
});

内容的提问来源于stack exchange,提问作者Archimedes Trajano

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:55:13