避免超时报错的关键是让异步行为可控可预测并主动约束执行时间边界:显式设 timeout、用 fake timers 替代真实定时器、mock 异步源头、优先使用 async/await + waitFor。

避免超时报错,关键不是延长测试时限,而是让异步行为完全可控、可预测,并在测试中主动约束执行时间边界。
显式设置合理 timeout 值
每个异步测试用例都应配明确的 timeout,避免依赖 Jest 默认 5 秒——边界测试往往需更短(如 50–200ms),防止“等太久才失败”掩盖逻辑缺陷。
- 在 test() 第三个参数传入: test('fetch with timeout', async () => { ... }, 100)
- 对 waitFor 等等待断言,单独设 timeout:await waitFor(() => expect(...).toBe(true), { timeout: 80 })
- 超时值应略大于你 mock 的延迟(比如 mock 了 50ms 延迟,timeout 设为 80ms),留出执行余量但不冗余
禁用真实定时器,用可控延迟替代
真实 setTimeout/setInterval 不可控,易受系统负载影响;必须用 jest.useFakeTimers() 替换,并配合 advanceTimersByTime() 或 runAllTimers() 主动推进时间。
- 在 test 开头调用 jest.useFakeTimers(),结尾用 jest.useRealTimers() 恢复
- 不要只 mock setTimeout —— fake timers 对 fetch/axios 无效,它只影响原生定时器;网络延迟必须靠 mock Promise 构造(如 new Promise(r => setTimeout(r, 50)))
- 验证超时逻辑时,先触发请求,再 advanceTimersByTime(60),再断言是否进入超时分支
拦截并控制异步源头,杜绝不可控等待
超时报错本质是某段异步逻辑没结束、没 reject、也没被 cancel。根源常在未 mock 的 fetch、axios、自定义定时器或事件监听器。
立即学习“Java免费学习笔记(深入)”;
- 用 vi.mock 或 jest.mock 替换所有外部请求模块,返回你完全掌控的 Promise(立即 resolve/reject,或带 delay 的可控 reject)
- 对 AbortController 场景,手动调用 abortController.abort() 并验证请求中断、回调未执行、清理逻辑(如 clearTimeout)已触发
- 检查组件或函数内部是否遗漏 clearTimeout / removeEventListener / unsubscribe,这些残留会拖住测试生命周期
优先用 async/await + waitFor,不用 done 回调
done 回调容易忘记调用,或在错误路径下未执行,导致测试挂起超时;async/await 配合 waitFor 语义清晰、堆栈友好、自动处理 Promise 生命周期。
- 写法统一为:test('...', async () => { await waitFor(...); })
- 避免:test('...', (done) => { ... setTimeout(done, 100); }) —— 一旦出错,done 不执行,测试就卡死
- waitFor 内部已集成超时机制,无需额外包裹 try/catch 或手动计时


















