async/await异步函数测试错误:参数为空时抛出异常的测试问题
嘿,这个场景我太熟悉了!异步函数的异常测试和同步函数确实不一样,毕竟异步的异常是封装在Promise的reject里的,不能直接用同步那套expect(() => ...).toThrow()的写法。这里有两种最常用的正确姿势,看你习惯哪一种:
方法1:用 async/await 配合 expect().rejects(推荐)
这是现代测试里最简洁直观的写法,完全贴合异步代码的风格。直接在测试函数前加async,然后用expect包裹你的异步函数调用,再链式调用.rejects.toThrow()就可以了:
it("should throw an error when type is undefined", async () => { // 可以测试任意假值场景:undefined、null、空字符串都可以 await expect(publish(undefined, {})).rejects.toThrow("Type is invalid: undefined"); // 如果不需要精确匹配错误信息,只关心是否抛出异常,也可以简化: // await expect(publish(undefined, {})).rejects.toThrow(); });
注意一定要加await!不然测试会在Promise完成前就结束,根本抓不到reject的异常,导致测试误判通过。
方法2:用Promise的 .catch() + done 回调
如果你的测试框架(比如Jest、Mocha)支持done回调,也可以用这种传统的异步测试写法:
it("should throw an error when type is undefined", (done) => { publish(undefined, {}) .catch(error => { // 验证错误信息是否符合预期 expect(error.message).toBe("Type is invalid: undefined"); // 必须调用done(),告诉测试框架这个异步测试已经完成 done(); }); });
这里要注意两个点:
- 一定要调用
done(),否则测试会超时失败,因为框架不知道什么时候异步流程结束 - 如果函数意外地resolve了(没有抛出异常),
catch不会执行,done()也不会被调用,最终测试会超时,这其实也能帮你发现代码的问题
为啥之前同步的测试简单?因为同步函数的异常是立即抛出的,测试框架可以直接捕获;但异步函数的异常是通过Promise reject传递的,必须等待Promise状态变化才能捕获到异常。
内容的提问来源于stack exchange,提问作者josemigallas
相关产品推荐
相关产品推荐

