异步代码测试需统一框架(如Jest)、建模模板(Promise/定时器/API等)、强制错误覆盖与CI质量门禁,杜绝裸回调和未处理异常。

异步代码测试在 JS 项目中不是“加个 done() 就完事”的事,而是关系到功能稳定性、CI 通过率和线上故障拦截能力的关键环节。团队落地的核心,是把“能测”变成“必须测、容易测、测得准”。
统一测试框架与断言风格
避免每个成员用不同工具写测试(有人用 Nodeunit,有人用 Jest,还有人手写 setTimeout + assert)。推荐明确主选方案,例如:
- Jest 作为默认框架:开箱即用的异步支持(
async/await、jest.fn()、jest.useFakeTimers()),适合大多数业务场景 - Mocha + Chai 用于需要高度定制报告或与旧系统兼容的项目,但需强制约定
done或return Promise的写法 - 禁用裸回调式测试(如
test('xxx', function(done) { ... })中不调用done()或漏写catch)
为常见异步模式建模测试模板
团队不必每次重写逻辑。可沉淀几类高频模板,放在内部文档或 CLI 脚手架中:
- Promises:直接
await+ 断言,失败时自动抛错 - 定时器(
setTimeout/setInterval):用jest.useFakeTimers()控制时间流,避免测试超时或不稳定 - 事件触发(如
EventEmitter、自定义事件):用once或waitForEvent工具函数封装监听逻辑 - API 请求:用
msw(Mock Service Worker)或jest.mock('node-fetch')统一拦截,禁止真实网络调用
把异步错误检查纳入评审硬性项
很多异步 bug 来自“只管成功路径”。代码评审时必须确认:
- Promise 链末尾是否有
.catch()或try/catch?未处理 rejection 在 Node.js 中会触发unhandledRejection事件,CI 应配置为失败 - 异步回调函数中是否检查了
err参数(尤其在遗留回调风格代码中)? - 测试用例是否覆盖了异常分支?例如 mock 一个失败的 fetch,验证错误状态是否正确渲染或上报
CI 中强制异步测试质量水位
仅“跑通”不够,要防退化:
- 启用 Jest 的
--detectOpenHandles,捕获未清理的定时器或 socket,避免测试间污染 - 设置超时阈值(如
--testTimeout=5000),过长的异步等待说明逻辑或 mock 有问题 - 要求新增异步逻辑时,必须附带对应测试;MR 检查项中加入“异步路径覆盖率 ≥90%”(可用
jest --coverage+ 自定义脚本校验)











