Mocha测试中expect校验异步函数抛错时,函数未抛错测试仍通过问题求助
问题原因
- 首先你误用了Chai的
throw断言的传参规则:同步场景下的throw断言要求传入函数本身,写法为expect(函数名).to.throw(),你直接传入throwError()相当于先执行函数拿到返回值再传给断言,本身就不符合同步throw断言的使用要求。 - 其次
throw断言本身不支持异步函数/ Promise的检测:async函数执行后返回的是Promise对象,即使函数内部抛出错误,本质也是Promise变为rejected状态,不会同步抛出异常,普通throw断言无法识别这种场景。 - 你写的
await expect(...).throw没有触发任何有效断言逻辑:未挂载chai-as-promised插件时,expect()返回的是普通断言对象,不是Promise,加await不会产生任何等待逻辑,也没有触发断言失败的条件,所以不管异步函数是否抛出错误,测试都会直接判定为通过,属于典型的假阳性结果。
修复方案
方案1:使用Chai as Promised插件(推荐)
这是异步Promise断言的标准方案,首先安装并挂载插件:
const chai = require('chai'); const chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); const expect = chai.expect;
调整断言写法如下即可正常检测异步抛错:
describe("bar", function(){ it("异步函数抛出错误时测试通过", async function() { await expect(throwError()).to.be.rejectedWith("foo"); }) }) describe("bar", function(){ it("异步函数未抛出错误时测试正常失败", async function() { await expect(notThrowError()).to.be.rejectedWith(); }) })
方案2:手动try/catch捕获判断
如果不想引入额外插件,可以手动捕获异步执行结果校验:
it("手动捕获异步错误校验", async function() { let caughtError = null; try { await notThrowError(); } catch (err) { caughtError = err; } expect(caughtError).to.be.an.instanceOf(Error); expect(caughtError?.message).to.equal("foo"); })
内容的提问来源于stack exchange,提问作者Jorge Montejo
相关产品推荐
相关产品推荐

