编写健壮的异步边界测试用例,核心是显式控制异步时机、覆盖完成/失败/超时/竞态等临界状态,并隔离外部依赖;需用 mock 控制 promise 的 resolve/reject 时机,验证超时取消、竞态处理及完整生命周期状态流转。

编写健壮的异步边界测试用例,核心是**显式控制异步时机、覆盖完成/失败/超时/竞态等临界状态,并隔离外部依赖**。不能只测“正常走通”,而要主动触发边界行为。
用 mock 控制 Promise 的 resolve/reject 时机
避免依赖真实网络或定时器,用 Jest 或 Sinon mock 返回可控的 Promise:
- 模拟立即 resolve:返回
Promise.resolve(data) - 模拟延迟 resolve:返回
new Promise(r => setTimeout(() => r(data), 100)) - 模拟立即 reject:返回
Promise.reject(new Error('timeout')) - 模拟延迟 reject:用
setTimeout+reject触发错误分支
显式测试超时与取消逻辑
真实场景中,fetch、axios、AbortController 都支持超时或取消。测试必须覆盖:
- 设置较短 timeout(如 50ms),确保被触发并进入错误处理分支
- 手动调用
abortController.abort(),验证请求是否真正中断、后续回调不执行 - 检查清理逻辑:比如是否移除了事件监听器、清空了定时器、重置了 loading 状态
验证竞态条件(Race Conditions)
多个异步操作并发时,后发先至可能覆盖前序结果(如搜索建议、分页加载)。测试要点:
- 发起两个请求:慢请求先发、快请求后发
- 断言最终 UI 或状态只反映快请求的结果
- 确保慢请求的回调被忽略(可用 mock 的
mock.calls.length检查是否未执行) - 对 React 组件,可结合
act+waitFor验证渲染结果是否稳定
断言异步副作用的完整生命周期
不要只测“最终状态”,要确认中间过程符合预期:
- 初始状态(如
loading: false, data: null, error: null) - 发起后立即变为
loading: true(同步更新) - 成功后
loading: false, data: xxx, error: null - 失败后
loading: false, data: null, error: xxx - 使用
await waitFor(() => expect(...).toBe(...))分阶段断言
不复杂但容易忽略:每个异步测试用例都应有明确的 timeout(Jest 默认 5s,但边界测试常需更短),且避免使用 done 回调——优先用 async/await + waitFor,语义清晰、错误堆栈友好。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











