为何expect断言在结果不等时仍通过?异步测试问题排查
为什么我的Mocha测试在实际结果和预期结果不同时仍通过?
问题核心:异步代码的执行顺序错误
你遇到的这个“假通过”问题,本质是同步代码和异步代码的执行顺序不匹配。
现在的代码里,expect(result).to.equal(expectedResult);是同步执行的,但result和expectedResult的赋值逻辑是放在Promise的.then()回调里的——这些回调会在当前所有同步代码执行完毕后才会触发。
具体的执行流程是:
- 初始化
result和expectedResult为空字符串 - 发起两个异步Promise请求(
reversify和readJsonFile) - 直接进入
finally块,执行expect("").to.equal(""),两个空字符串当然相等,测试直接通过 - 等到Promise请求完成,
.then()回调才开始给变量赋值,但此时测试已经结束了,根本不会影响之前的断言结果
解决方案:正确处理异步测试
Mocha提供了多种优雅处理异步测试的方式,这里推荐两种最常用的:
方式1:使用async/await(代码最简洁,推荐)
把测试函数标记为async,用await等待所有Promise完成,确保断言前拿到真实的结果和预期值:
describe("reversify", () => { it("Should reverse file", async ()=> { try{ // 用await等待两个Promise完成,拿到真实结果 const result = await reversify("./test/json_files/inputs/t1.json"); const expectedResult = await readJsonFile("./test/json_files/outputs/t1.json"); console.log('Result is: ', result); console.log("Expected Result is: ", expectedResult); // 用deep.equal对比对象数组的深层结构,不要用equal(只会对比引用) expect(result).to.deep.equal(expectedResult); } catch(err) { throw err; // 抛出错误,Mocha会自动标记测试失败 } }); });
方式2:使用Mocha的done回调
如果你的环境不支持async/await,可以用Mocha提供的done参数来标记异步测试的结束:
describe("reversify", () => { it("Should reverse file", (done)=> { // 用Promise.all同时等待两个异步操作完成 Promise.all([ reversify("./test/json_files/inputs/t1.json"), readJsonFile("./test/json_files/outputs/t1.json") ]).then(([result, expectedResult]) => { console.log('Result is: ', result); console.log("Expected Result is: ", expectedResult); expect(result).to.deep.equal(expectedResult); done(); // 调用done,告诉Mocha测试已完成 }).catch(err => { done(err); // 把错误传给done,Mocha会标记测试失败 }); }); });
额外提示
- 不要用
JSON.stringify来对比对象:JSON字符串化可能会因为属性顺序、空格换行等细节导致不必要的失败,deep.equal才是对比对象/数组深层结构的可靠方式。 - 你的
finally块在这里完全没用:因为异步操作还没完成就会进入finally,根本起不到等待结果的作用,直接去掉即可。
内容的提问来源于stack exchange,提问作者Anant Sinha
相关产品推荐
相关产品推荐

