如何用Mocha/Chai测试延迟抛出异常的异步函数?
解决Mocha/Chai测试异步函数抛异常的问题
嗨,我来帮你搞定这个异步函数的测试坑~你的问题核心是没让Mocha正确等待异步操作完成,导致测试提前通过,之后才抛出异常。咱们一步步来修正:
先分析你第一种写法的问题
你写的:
expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)).to.eventually.throw();
这里的问题是没有把这个断言的Promise返回给Mocha,Mocha看不到这个Promise,就会认为测试已经执行完成,直接标记通过,根本不会等2秒后的异常抛出。
正确的测试写法
方法1:用Chai-as-promised的eventually并返回Promise
只要把断言的Promise返回给Mocha,它就会自动等待异步操作完成:
it('should reject after 2 seconds', () => { // 返回这个Promise,让Mocha等待 return expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)) .to.eventually.be.rejected; });
如果需要匹配具体的异常类型或消息,可以用rejectedWith:
return expect(publisher.dispatchMessage(...)) .to.eventually.be.rejectedWith(Error, '你的异常提示内容');
方法2:用async/await配合Chai的断言
如果你习惯用async/await风格,直接在测试函数里await断言即可(同样要确保Mocha能捕获到异步操作):
it('should reject after 2 seconds', async () => { // 注意:异步函数的异常是Promise reject,要用rejected断言,不是throw await expect(publisher.dispatchMessage<ExampleResponseMessage>(message, {}, 2 * 1000)) .to.be.rejected; // 匹配具体错误的写法 await expect(publisher.dispatchMessage(...)) .to.be.rejectedWith(Error, '预期的异常文本'); });
额外注意:Mocha超时设置
Mocha默认的测试超时时间是2000ms,你的函数刚好在2000ms后抛异常,很容易触发超时导致测试失败。建议把测试的超时时间设长一点,比如3000ms:
it('should reject after 2 seconds', async () => { this.timeout(3000); // 单个测试用例设置超时 await expect(publisher.dispatchMessage(...)) .to.be.rejected; });
或者在describe块里设置全局超时,让整个测试套件都适用:
describe('Publisher tests', () => { this.timeout(3000); it('should reject after 2 seconds', async () => { await expect(publisher.dispatchMessage(...)) .to.be.rejected; }); });
这样修改后,测试就会正确等待2秒,直到异步函数抛出异常,再判断断言是否符合预期啦~
内容的提问来源于stack exchange,提问作者kentor
相关产品推荐
相关产品推荐

