Promise链式中断测试核心是验证中断逻辑是否主动触发、精准生效且无副作用,需控制中断点、隔离后续执行、断言拒绝行为及状态,覆盖降级路径与副作用检查。

测试 Promise 链式中断,核心不是看“链断了没”,而是验证中断逻辑是否按设计主动触发、精准生效、不引发副作用。关键在于控制中断点、隔离后续执行、断言状态与行为是否符合预期。
明确中断触发条件并隔离测试
链式中断通常由显式拒绝(reject)、抛错、return Promise.reject() 或 throw 触发。测试前先确认中断由哪一步发起:
- 若中断发生在第 2 步(如
.then(() => { throw new Error('stop') })),就只 mock 前两步,确保第 1 步 resolve 后,第 2 步确实抛错 - 避免全链运行——用 Jest mock 掉后续步骤(如
jest.mock('./service', () => ({ save: jest.fn() }))),再检查save是否从未被调用 - 对条件中断(如“仅当用户未登录时中断”),通过 mock 状态变量(如
mockAuthState({ isLoggedIn: false }))复现路径
用 expect().rejects 断言中断结果
中断最终会表现为链的终止和错误上抛,应直接验证 Promise 的拒绝行为:
- 正确写法:
await expect(fullChain()).rejects.toThrow('stop')—— 框架自动等待并捕获拒绝,语义清晰 - 不要写
expect(() => fullChain()).toThrow():async 函数同步返回 Promise,永远不会同步抛错,该断言必过且无意义 - 需要校验错误结构时,用
.rejects.toMatchObject({ code: 'AUTH_REQUIRED' })或.rejects.toBeInstanceOf(AuthError)
验证中断后无副作用残留
中断不只是“不往下走”,更要确保不该发生的操作真的没发生:
立即学习“前端免费学习笔记(深入)”;
- 检查网络请求是否被取消:mock
fetch,断言fetch.mock.calls.length === 0 - 检查本地存储是否未写入:mock
localStorage.setItem,确认调用次数为 0 - 检查定时器是否未启动:若中断逻辑含
setTimeout,配合jest.useFakeTimers()+jest.getTimerCount()验证计时器数量为 0
覆盖中断恢复与降级路径
真实场景中,中断常伴随兜底处理(如跳过某步、返回默认值、调用备选接口)。测试需主动构造中断,再验证降级是否生效:
- 例如链为
fetch → validate → save,让validate拒绝,但链末尾有.catch(() => getDefaultData()),则断言最终 resolve 值等于默认数据 - 用
jest.fn().mockRejectedValueOnce(...)控制仅第一次失败,验证重试逻辑是否触发;或用AbortSignal主动 abort,确认后续 Promise 被正确取消且无副作用 - 对可选步骤(如“仅在调试模式记录日志”),mock 环境变量后检查
console.warn是否被调用,确保中断时日志逻辑也受控


















