Mocha测试Promise用例首次断言失败后进程冻结问题排查求助
问题原因
- 异步测试逻辑混用了
async/await和done回调两种异步处理方式
Mocha的异步测试规则为:如果测试回调声明了done参数,框架只会等待done被主动调用,不会监听回调返回的Promise状态。你在async函数内执行断言,当assert.equal(sum,5)失败抛出异常时,异常会被async函数捕获为 rejected Promise,后续的done()永远不会执行,框架无法收到测试结束信号,就会陷入永久等待的冻结状态。
当sumInPromise不是Promise类型时,你不需要加await,断言失败会同步抛出异常,Mocha可以直接捕获同步异常,所以运行符合预期。 - before钩子内存在同步死循环风险
你在initStart的then回调中加入了while(app == null)的空循环,JavaScript是单线程执行模型,这个空循环会完全阻塞事件循环,只要进入循环逻辑,app变量永远无法被其他逻辑赋值,会直接导致进程卡死。
解决方案
- 异步测试二选一使用异步处理方式,推荐直接使用async函数,删除
done参数,Mocha会自动监听async函数返回的Promise状态,断言失败会自动识别为测试失败,无需手动调用结束信号。 - 删除before钩子内的空轮询逻辑,
initStart的then回调触发即代表服务初始化完成,直接调用done即可。
修改后的代码示例:
describe("Dummy test", () => { before((done: Done) => { app ? done() : initStart() .then(() => done()) .catch((err) => done(err)); }); after((done: Done) => { app ? done() : closeServer() .then(() => done()) .catch((err) => done(err)); }); const sumInPromise = (a: number, b: number) => { return Promise.resolve(a + b); }; it("OK, dummyPromise", async () => { const sum = await sumInPromise(2, 2); assert.equal(sum, 5); }); });
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

