如何使用 toThrow 和 Jest 断言异步方法抛出错误

Posted

技术标签:

【中文标题】如何使用 toThrow 和 Jest 断言异步方法抛出错误【英文标题】:How to assert an async method throwing Error using toThrow with Jest 【发布时间】:2019-07-01 23:34:36 【问题描述】:

我已经看到 this question 期望 Promise 可以工作。在我的情况下,Error 被抛出在 Promise 之前和之外。

在这种情况下如何断言错误?我已经尝试了以下选项。

test('Method should throw Error', async () => 

    let throwThis = async () => 
        throw new Error();
    ;

    await expect(throwThis).toThrow(Error);
    await expect(throwThis).rejects.toThrow(Error);
);

【问题讨论】:

【参考方案1】:

调用throwThis 会返回一个Promise,它应该用Error 拒绝,所以语法应该是:

test('Method should throw Error', async () => 

  let throwThis = async () => 
    throw new Error();
  ;

  await expect(throwThis()).rejects.toThrow(Error);  // SUCCESS
);

请注意,toThrow 已针对 PR 4884 和 only works in 21.3.0+ 中的承诺进行了修复。

所以 这只有在您使用 Jest 22.0.0 或更高版本时才有效。


如果您使用的是早期版本的Jest,您可以将spy 传递给catch

test('Method should throw Error', async () => 

  let throwThis = async () => 
    throw new Error();
  ;

  const spy = jest.fn();
  await throwThis().catch(spy);
  expect(spy).toHaveBeenCalled();  // SUCCESS
);

...并可选择检查Error 抛出的by checking spy.mock.calls[0][0]

【讨论】:

(只是一个补充)await expect(throwThis()).rejects.toEqual(expect.any(Error)); 也可以(我相信即使是老的jest 谢谢!我使用的是最新的 (24.1),所以第一个示例有效。 @Darlesson 不客气,很高兴听到它有帮助! @skyboyer 很好,真的很干净。只要您不需要检查有关 Error 的任何详细信息,这是一个不错的方法,我刚刚验证它至少可以回到 20.0.4 版本。 出于某种原因,第一个示例总是给我一个“正确”的测试。它从未失败,即使它应该失败。我选择了第二个,它奏效了。

以上是关于如何使用 toThrow 和 Jest 断言异步方法抛出错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在不失败测试的情况下获得 Jest toThrow 的覆盖率

rejects.toThrow in Jest

为啥直接在构造函数中创建 ES6 类的实例时 Jest 的 toThrow 不起作用?

如何断言哪个值已传递给 <li> 键属性以与 jest 和 testing-library/react 反应

开玩笑 - 断言异步函数抛出测试失败

vue-cli 项目集成 Jest 单元测试