如何Mock方法/函数返回预期错误?Jest/TypeScript异步测试问题
解决Jest测试异步函数错误场景的问题
我明白你遇到的问题啦——异步函数的错误测试逻辑和同步函数不一样,直接用toThrow()肯定抓不到异常,因为async函数返回的是Promise,错误会转化为Promise的reject状态,而不是同步抛出的异常。
咱们来调整下测试代码,两种方法都能解决这个问题:
方法一:用async/await结合rejects.toThrow()
这是最直观的写法,你的测试本身就是async函数,直接await目标Promise,并用rejects断言捕获错误:
it('handles errors gracefully', async () => { expect.assertions(1); const cfMock = { listStacks: (): any => ({ promise: async () => { throw new Error('ohh NOO!'); } }) }; // 用rejects断言Promise会被reject,且抛出指定错误 await expect(listStacks(cfMock as CloudFormation)).rejects.toThrow('ohh NOO!'); });
方法二:返回Promise并使用rejects断言
如果不想用async/await,也可以直接返回这个Promise,让Jest自动等待它完成:
it('handles errors gracefully', () => { expect.assertions(1); const cfMock = { listStacks: (): any => ({ promise: async () => { throw new Error('ohh NOO!'); } }) }; // 返回Promise,Jest会自动等待其状态变更 return expect(listStacks(cfMock as CloudFormation)).rejects.toThrow('ohh NOO!'); });
为什么原来的代码不生效?
你之前用expect(() => listStacks(...)).toThrow(),但listStacks()是async函数,调用它时不会同步抛出错误,而是立刻返回一个Promise,错误只会在这个Promise被reject时才触发。同步的toThrow()根本抓不到异步的错误,所以Jest才会提示你“Received function did not throw”。
另外,你保留expect.assertions(1)是非常正确的,它能确保测试中至少有一个断言被执行,避免因为Promise未被正确处理而导致测试意外通过的情况。
内容的提问来源于stack exchange,提问作者Galty
相关产品推荐
相关产品推荐

