期望函数在 Jest 中抛出异常

Posted

技术标签:

【中文标题】期望函数在 Jest 中抛出异常【英文标题】:Expect a function to throw an exception in Jest 【发布时间】:2020-05-01 23:37:30 【问题描述】:

我有一个返回承诺的函数 (hostelService.book):return Promise.resolve(response); 我做了这个测试:

const action = async () => 
        await hostelService.book(id);
    ;


  await expect(action).rejects.toThrow();

但我有这个错误:

 Matcher error: received value must be a promise

【问题讨论】:

只有toThrow 调用提供的值。 rejects 要求它已经是一个promise,而不是一个返回一个promise的函数。我认为.rejects.toThrow() 根本没有意义;你可能想要expect(hostelService.book(id)).rejects.toEqual(someError)。见jestjs.io/docs/en/tutorial-async.html#rejects。 【参考方案1】:

Jest 抛出此错误Matcher error: received value must be a promise,因为在expect 中您只是传递函数引用。没有() - action 只是一个函数引用,它不会返回任何内容。

要解决此问题,您必须像 action() 一样在 expect 中调用函数,以便它返回 promise 对象。

第二部分,你必须抛出错误。 Promise.reject(new Error('some error')); 在拒绝中,因此 tothrow 条件可以完全填充。

示例:

function hostelService() 
   return Promise.reject(new Error('some error'));


const action = async () => 
   await hostelService();
;

it( "Should throw the error", async () => 
   await expect(action()).rejects.toThrow('some error');
);

希望这会有所帮助。

【讨论】:

【参考方案2】:

看来你差不多了。我创建了一个代码沙盒,其中包含一个引发错误的函数和一个通过的测试。您可以在代码沙箱内的终端中使用npm run test 运行它。这是链接:

https://codesandbox.io/s/musing-goodall-ssss4?fontsize=14&hidenavigation=1&theme=dark

但基本上代码是这样的:

const action = async () => 
  throw new Error("error!")


describe("func", () => 
  it("should fail", async () => 
    await expect(action()).rejects.toThrow()
  )
)

与您显示的代码的区别在于缺少action() 中的调用,可能是类型错误。我不知道这是一个错误还是不仅仅是代码,你只是想解释你想要什么。将来,为了更好地理解并帮助您未来的“助手”,您应该发布您的代码的 sn-p(或修改以避免属性问题)。

【讨论】:

【参考方案3】:

您的测试失败,因为您正在等待承诺(因此,当您在其上调用 .rejects 时,它不再是 Promise)。如果您从最后一条语句中删除 await,它应该可以解决问题:

const action = async () => 
  await hostelService.book(id);
;

expect(action()).rejects.toThrow();

这是它背后的一些基本原理。 async 自动将您的返回类型包装到 Promise 中。但是,当您调用 await 时,它会同步“解包”给定 Promise 的值,因此它不能在结果上调用 .rejects(除非您将 Promise 包装到另一个 Promise 中)。

我写了a small example 来说明我的意思。

【讨论】:

【参考方案4】:

很遗憾,您无法直接使用 toThrow() 测试拒绝。拒绝它自己是一个错误对象,因此您可以测试是否相等。

test('', () => 
  // dont forget to call the action. 
  await expect(action()).rejects.toEqual(new Error())
);

您可以在这里找到更多解决方法https://github.com/facebook/jest/issues/1700

【讨论】:

【参考方案5】:

这里的 action 就是函数,你不是从期望中调用它。我还从最后一行删除了等待

试试这个解决方案

const action = async () => 
  await hostelService.book(id);
;
expect(action()).rejects.toThrow();

【讨论】:

您最后的评论不正确。您不应从 expect(...).rejects.toThrow('some message'); 语句中删除 await。它可能会或可能不会起作用,具体取决于它是否是测试的最后一条语句等,但您实际上所做的是在异步代码仍在执行的情况下完成测试,这可能意味着您将在测试中调用拆解代码。在测试中始终等待异步调用。

以上是关于期望函数在 Jest 中抛出异常的主要内容,如果未能解决你的问题,请参考以下文章

为啥在构造函数中抛出异常会导致空引用?

为啥在析构函数中抛出异常时不调用重载删除?

不要在构造函数中抛出异常

Java:构造函数中抛出异常,我的对象仍然可以创建吗?

在Scala中抛出异常,啥是“官方规则”

从匿名内部类的构造函数中抛出异常