简体   繁体   English

期望一个函数在 Jest 中抛出异常

[英]Expect a function to throw an exception in Jest

I have a function ( hostelService.book ) that returns a promise: return Promise.resolve(response);我有一个返回承诺的函数( hostelService.book ): return Promise.resolve(response); and I made this test:我做了这个测试:

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


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

but I have this error:但我有这个错误:

 Matcher error: received value must be a promise

Jest is throwing this error Matcher error: received value must be a promise because in expect you are just passing the function reference. Jest 抛出此错误Matcher error: received value must be a promise因为在expect您只是传递函数引用。 Without () - action is just a function reference it will not return anything.没有() - action只是一个函数引用,它不会返回任何东西。

To fix this issue you have to call the function in expect like action() so it will return the promise object.要解决此问题,您必须像action()一样在 expect 中调用该函数,以便它返回 promise 对象。

And the second part, you have to throw error like.第二部分,你必须抛出错误。 Promise.reject(new Error('some error')); in the reject so the tothrow condition can be full filled.在拒绝中,因此可以完全填充tothrow条件。

Example:例子:

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');
});

Hope this will be helpful.希望这会有所帮助。

Your test fails because you're awaiting the promise (and therefore, it is no longer a Promise when you call .rejects on it).您的测试失败,因为您正在等待承诺(因此,当您对其调用.rejects时,它不再是 Promise)。 If you remove await from the last statement, it should do the trick:如果您从最后一个语句中删除await ,它应该可以解决问题:

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

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

Here is some rationale behind it.这是其背后的一些基本原理。 async automatically wraps your return type into a Promise. async自动将您的返回类型包装到一个 Promise 中。 However, when you call await , it synchronously "unwraps" the value of a given Promise and therefore it can't call .rejects on the result (unless you wrap a Promise into another Promise).但是,当您调用await ,它会同步“解开”给定 Promise 的值,因此它无法对结果调用.rejects (除非您将一个 Promise 包装到另一个 Promise 中)。

I've composed a small example to illustrate what I mean.我编写了一个小例子来说明我的意思。

It seems you almost have it.看起来你几乎拥有它。 I have created a codesandbox with a function that throws an error and a test that passes.我创建了一个带有抛出错误和通过测试的函数的代码沙盒。 You can run it with npm run test in a terminal inside codesandbox.您可以在代码沙盒内的终端中使用npm run test运行它。 Here's the link:这是链接:

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

But basically the code is this:但基本上代码是这样的:

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

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

The difference with the code you showed is the call in action() that was missing, maybe that was the type error.与您显示的代码的不同之处在于缺少action()中的调用,这可能是类型错误。 I don't know if that was a mistake or it wasn't just code and you just meant to explain what you wanted.我不知道这是否是一个错误,或者这不仅仅是代码,而您只是想解释您想要什么。 In the future, for better understanding and to help your future "helpers", you should post a snippet of your code (or modified to avoid property issues).将来,为了更好地理解并帮助您未来的“帮手”,您应该发布您的代码片段(或修改以避免属性问题)。

Here action is function and you're not calling it from expect.这里的动作是函数,你不是从期望中调用它的。 I've also removed await from last line我还从最后一行中删除了 await

Try this solution试试这个解决方案

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

Unfortunately you can't test rejects directly with toThrow() .不幸的是,您不能直接使用toThrow()测试拒绝。 Rejects it self is an error object so you can test for equality.拒绝它自己是一个错误对象,因此您可以测试是否相等。

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

You can find more workarounds here https://github.com/facebook/jest/issues/1700您可以在此处找到更多解决方法https://github.com/facebook/jest/issues/1700

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM