Mocha测试因SUT未完成Promise静默失败问题咨询
问题原因与解决方案
核心问题:代码存在语法错误
你的测试代码里有明显语法错误,导致Node.js进程直接终止,Mocha根本没机会进入等待Promise的逻辑:
// 原错误代码 let firstPromise = new Promise((resolve, reject) => { console.log("I do something, but forget to resolve secondPromise"));
这里存在两个语法问题:
console.log的括号未闭合,多写了一个右括号- Promise构造函数的回调函数只写了开括号
{,没有闭合的}
这个错误会触发Node.js的未捕获语法异常,直接终止整个测试进程,所以Mocha来不及等待secondPromise完成,就直接静默退出了。
修正语法后的行为
把代码修正为合法语法后:
describe("stupid me promise", () =>{ it("why does this not work?", async () => { let secondResolve: (val:unknown) => void; let secondPromise = new Promise((resolve, reject) => { secondResolve = resolve; }); // 修正语法错误 let firstPromise = new Promise((resolve, reject) => { console.log("I do something, but forget to resolve secondPromise"); // 此处是否resolve不影响,因为未被await }); console.log("Awaiting a promise, that never completes"); await secondPromise; console.log("This line here never gets hit. The test exists silently"); expect(true).to.be.false; }); });
此时如果用--no-timeouts参数运行,Mocha会一直挂起,因为它在等待secondPromise的状态变更;如果没有--no-timeouts,Mocha会在默认超时时间(通常2000ms)后标记测试为失败。
为什么之前的参数没生效?
你尝试的--async-only、--forbid-pending等参数,都基于测试代码能正常执行到异步逻辑的前提。但因为语法错误导致进程直接终止,这些参数根本没机会发挥作用。
如何检测这类未完成的Promise?
如果想让Mocha在遇到永远不resolve的Promise时主动失败,可以:
- 去掉
--no-timeouts,依赖Mocha的默认超时机制,超时后测试会自动失败 - 手动给Promise添加超时逻辑:
// 给secondPromise添加超时限制 const timeoutPromise = new Promise((_, reject) => { setTimeout(() => reject(new Error("Promise timed out")), 5000); }); // 等待任一Promise完成 await Promise.race([secondPromise, timeoutPromise]);
内容的提问来源于stack exchange,提问作者Samuel
相关产品推荐
相关产品推荐

