javascript异步队列单元测试核心是验证执行顺序、错误处理、并发控制与状态一致性;需用jest假计时器精确控制时序,记录日志断言中间态,注入失败任务检验恢复能力,并通过计数逻辑验证并发上限。

JavaScript 异步队列的单元测试,核心是验证任务是否按预期顺序执行、是否正确处理错误、是否支持并发控制或串行保障——而不是测“它是不是异步”。重点在于模拟异步行为、隔离外部依赖、断言执行时序和状态变化。
用 Jest 模拟异步行为并控制时间流
不依赖真实 setTimeout 或 Promise.resolve(),改用 Jest 的 jest.useFakeTimers() 和 jest.runAllTimers() 或 jest.advanceTimersByTime() 来精确控制微任务/宏任务的触发时机。
- 调用
jest.useFakeTimers('modern')启用现代计时器(兼容 Promise 微任务) - 用
await jest.runAllTimersAsync()确保所有微任务(如 Promise.then)和宏任务(如 setTimeout)依次清空 - 避免
setTimeout(() => {}, 0)这类不可控延迟,统一用Promise.resolve()或queueMicrotask()模拟微任务调度
断言任务执行顺序与状态一致性
异步队列的关键逻辑常涉及共享状态(如 loading 标志、计数器、响应缓存)。测试时需捕获中间态,而非只看最终结果。
- 用数组
const log = []记录每个任务的执行时间点或关键动作(如 “task1 start”, “task2 resolve”) - 在任务函数内部插入
log.push('taskX started')和log.push('taskX done'),再断言expect(log).toEqual([...]) - 对互斥锁(Mutex)或信号量(Semaphore)类队列,额外断言:同一时刻仅一个任务处于 active 状态,且释放后下一个才开始
覆盖错误传播与恢复能力
真实场景中,队列内某个任务失败不应导致整个队列卡死或后续任务跳过。测试要显式注入 reject,并验证队列是否继续调度。
- 构造一个会
reject(new Error('oops'))的任务,观察后续任务是否仍被执行 - 若队列提供
onError钩子或返回带 error 处理的 Promise,需断言回调被调用,且参数正确 - 避免静默吞错:检查未 catch 的 Promise rejection 是否触发
jest.mock('console', () => ({ error: jest.fn() }))并断言其调用
验证并发控制逻辑(如 Semaphore)
若队列支持最大并发数(例如同时最多执行 2 个 fetch),测试需构造超量任务并确认实际并发数未超标。
- 启动 5 个异步任务,每个任务开头记录
activeCount++,结尾activeCount-- - 用
jest.fn().mockImplementation(() => new Promise(...))包裹任务体,插入计数逻辑 - 在任意时刻断言
expect(activeCount).toBeLessThanOrEqual(2),尤其关注峰值时刻 - 可配合
jest.advanceTimersByTime(1)步进式推进,观察并发数波动
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











