测试异步请求超时中断需模拟指定时间后未完成的场景,优先用AbortController手动abort验证reject;其次mock fetch或Axios延迟响应,断言超时错误;避免真实网络延迟,注意清理定时器和区分网络/业务超时。

测试异步请求超时中断逻辑,核心是控制请求“在指定时间后不完成”,并验证代码是否正确触发超时处理(如抛错、调用 abort、执行 fallback 等)。不能依赖真实网络延迟,而应主动模拟超时场景。
用 AbortController 主动中断 fetch 请求
现代 fetch 支持 AbortSignal,是测试超时中断最贴近真实的方案。关键是在测试中手动调用 abort(),而不是等真实超时:
- 创建 AbortController 实例,传入其 signal 到 fetch
- 用 setTimeout 在指定毫秒后调用 controller.abort()
- 断言 Promise 被 reject,且错误是 DOMException(name === 'AbortError')
示例(Jest):
test('fetch 超时被 AbortController 中断', async () => {
const controller = new AbortController();
// 模拟一个永远不响应的请求(或用 mock 返回 Promise<void>)
const promise = fetch('/api/data', { signal: controller.signal });
setTimeout(() => controller.abort(), 100);
await expect(promise).rejects.toThrow('AbortError');
});
用 jest.mock 模拟 fetch 并延迟 resolve/reject
更可控的方式是 mock fetch,让它在超时时间之后才 resolve 或 reject,再验证你的业务逻辑是否在超时前就调用了 abort 或走到了 timeout 分支:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- mock fetch 返回一个 Promise,内部用 setTimeout 延迟 resolve
- 确保你的函数内部设置了超时逻辑(如封装了 AbortController 或定时器)
- 断言:函数返回的 Promise 在超时时间后被 reject,且错误信息符合预期
例如你封装了一个带超时的请求函数 fetchWithTimeout(url, timeout):
jest.mock('node-fetch', () => jest.fn());
test('fetchWithTimeout 在 200ms 后正确超时', async () => {
// mock fetch 延迟 500ms 才返回
require('node-fetch').mockImplementation(() =>
new Promise(resolve => setTimeout(() => resolve({ ok: true }), 500))
);
await expect(fetchWithTimeout('/test', 200)).rejects.toMatch(/timeout/);
});
测试 Axios 的 timeout 配置或 CancelToken(旧版)
Axios 原生支持 timeout 选项(单位 ms),触发时会 reject 带 code: 'ECONNABORTED' 的错误:
- 直接配置 timeout: 100,mock axios.get 返回一个长延迟响应
- 断言错误对象有 code === 'ECONNABORTED' 和 message 包含 'timeout'
- 若用旧版 CancelToken,需 mock CancelToken.source() 并手动调用 cancel()
注意:Axios 的 timeout 是请求级超时(从发起到收到响应),不是连接超时,测试时 mock 响应延迟即可覆盖。
避免常见陷阱
写测试时容易忽略的关键点:
- 不要用 realFetch + 真实延时:CI 环境不稳定,易造成 flaky test
- 清理定时器:用 jest.useFakeTimers() 时记得 jest.runAllTimers() 或 jest.advanceTimersByTime(),避免未触发的 timeout 影响后续测试
- 区分网络超时和业务超时:有些逻辑在 fetch 成功后还做耗时处理(如解析大 JSON),这时需额外加业务层 timeout(如 Promise.race),测试也要覆盖该分支
- 检查 abort 是否真正生效:比如 fetch 被 abort 后,是否还执行了 .then() 里的逻辑?建议在 then/catch 里加 console.log 或 mock 函数验证

















