测试 Promise.all 需真实模拟并发:分别 mock 各异步函数,设置立即 resolve、延迟 resolve、延迟 reject 和永远 pending;验证短路行为、超时触发及清理逻辑,并确保测试隔离与多维断言完整。

测试 Promise.all 的竞态条件与超时处理,关键在于**真实模拟并发行为本身**,而非仅校验返回值。重点是让被 Promise.all 包裹的各个异步调用具备可控的完成时机、状态和中断能力。
精准控制每个 Promise 的时序与状态
不要 mock Promise.all 本身,而是 mock 它内部调用的每一个异步函数(如 API 方法),为它们分别设置不同响应:
- 一个立即 resolve(模拟快速接口)
- 一个延迟 800ms 后 resolve(模拟中等耗时)
- 一个延迟 2s 后 reject(模拟超时失败)
- 一个永远 pending(
new Promise(() => {}),用于触发 timeout 逻辑)
验证 Promise.all 的“短路”行为
Promise.all 遇到首个 reject 就立刻终止,不等待其余 Promise。测试需明确断言该特性:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 当第 2 个 Promise 抛错时,主流程应进入
.catch,且错误内容匹配预期 - 检查其他 Promise 是否仍在 pending 状态(可通过 jest.spyOn + mockImplementation 拦截并计数)
- 避免所有 mock 都同步 resolve —— 否则退化为顺序执行,无法暴露竞态问题
主动构造并触发超时边界
若业务中封装了超时逻辑(如配合 AbortController 或手动 race),测试必须覆盖中断瞬间:
- 用
jest.useFakeTimers()控制时间,快速推进到超时阈值 - 构造一个长期 pending 的 Promise 并传入 Promise.all,验证是否被 timeout 逻辑捕获并 reject
- 检查清理动作是否执行:比如 abortSignal.abort() 是否被调用、未完成请求是否被取消、资源是否释放
确保测试隔离与断言完整
每次测试前后要重置环境,同时验证多维结果:
- 使用
jest.clearAllMocks()和jest.restoreAllMocks()防止副作用干扰 - 断言不仅要看最终 error 或 data,还要检查:各 mock 函数的调用次数、传入参数、调用顺序
- 若用
Promise.allSettled替代,需断言返回数组中每个对象的status字段(fulfilled/rejected)及对应值

















