You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:28:51