[英]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.