-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rejects.toThrowError #3601
Comments
Try awaiting inside the |
It won't work... an error will be thrown and 'expect' cant catch that. |
Found it (I stumbled upon your issue because I had the same problem :))
Test passes on my machine. I think you can close it now. |
What we want is to match a error message (that is, the Otherwise it's easy to use something like |
Use toMatch instead of toEqual, then. Unless I missed your point, in which case I apologise. |
toMatch is what I want, the point of this bug is that it doesn't work :) See last example in the initial comment. |
Apologies, I should not try to help at this late time of the day. I now understood what you mean. It is a good point, but I believe that the example is incorrect, and not the implementation. Let me try to explain what I mean, I hope it makes a tiny bit of sense.
That works. If you look at the Javascript specification, a My two pennies worth of it. |
Mmm I see what you mean. Yet Jest's documentation use the example of a real error with toMatch :) see https://facebook.github.io/jest/docs/expect.html#rejects . Either the example in the doc is wrong, or the implementation is wrong :) I think this is needlessly difficult to check an error's message with Jest, especially when we want to match. |
@imeruli When using async/await you should write async foo() {
throw new Error('some error');
} not async foo() {
throw 'some error';
} |
Isentkiewicz, I do no not disagree, however, from a specification standpoint, it is written nowhere. |
See the "Description" section from the link you referred.
|
+1 on this. I use this for now: await expect(Promise.rejects(new Error('Some error')))
.rejects.toMatchObject({
message: 'Some error',
}); This is a temporary workaround if you are willing to match the whole error message. Obviously, jest should support such basic thing. |
+1 It would be great if I can use reject with an error object . |
What about a await expect(Promise.rejects(new Error('Some error')))
.rejects.withMessage('Some error'); Or even this: await expect(Promise.rejects(new Error('Some error')))
.rejects.message.toMatch('Some error'); |
As a workaround for this issue, I came up with this aproach:
If it doesn't throw, |
Im confused - why does the documentation (still!) contain an example that doesnt work (https://facebook.github.io/jest/docs/en/expect.html#rejects) and prusumedly never worked? Also why not solve it by having expect().toThrow() support promises? Then you could write:
|
+1 same here. |
@lachlanhunt that would work, of course, but it is extremely verbose compared to other jest workflows. Probably you also want to check before hand that err is actually defined (there was an error thrown), otherwise it'll give an unhelpful undefined error. BTW, for anyone reading so far, @ecstasy2 solution stopped working on Jest 21.0: #4532 |
To test multiple properties, the following is working: expect(promise).rejects.toHaveProperty('prop1', 'value1');
expect(promise).rejects.toHaveProperty('prop2', 'value2'); |
Is this considered a bug or just the way Jest is supposed to work? await expect(drinkOctopus).rejects.toMatch('octopus'); Which doesn't actually work if This feels cumbersome, to me. Is there a planned way to handle these rejections? |
IMO it's a bug (or missing feature, I suppose) (and as this has never been closed, I'm guessing other collaborators agree with me). Not really sure how to achieve symmetry with other matchers, but PR welcome! |
* fix .toThrow for promises fixes #3601 Signed-off-by: Łukasz Sentkiewicz <sirmims@gmail.com> * keep original matcherName Signed-off-by: Łukasz Sentkiewicz <sirmims@gmail.com> * fix flow Signed-off-by: Łukasz Sentkiewicz <sirmims@gmail.com> * update changelog Signed-off-by: Łukasz Sentkiewicz <sirmims@gmail.com>
@SimenB done :) |
Here is my solution: test('addItem mutation rejects invalid user', async () => {
try {
await addItem(root, noArgs, invalidContext)
} catch (e) {
expect(e.message).toMatch('You must be authenticated to run this query.')
}
}) It is essentially what @lachlanhunt posted. If you simply execute the function under test with the arguments necessary to output the expected error, you can observe it in the catch block and do a simple string check. |
@agm1984 your test will pass if |
* Need to await * Had to use this way to assert, as suggested here: jestjs/jest#3601 (comment)
As explained and based on the work here, I made a small function to help: // My final utility function, "synchronizer":
const sync = fn => fn.then(res => () => res).catch(err => () => { throw err });
// Example function for testing purposes
const check = async arg => {
if (arg > 5) throw new Error('Too large!');
if (arg < 0) throw new Error('Too small!');
return 'Good to go';
};
// Write the expect() in quite a clear way
it('checks the boundaries properly', async () => {
expect(await sync(check(-1))).toThrow(); // Can also take 'Too small!' or /Too small!/
expect(await sync(check(0))).not.toThrow();
expect(await sync(check(5))).not.toThrow();
expect(await sync(check(10))).toThrow();
}); It has the added benefit compared to |
These big threads like this are such a mess. Is the bug fixed? If it is could someone please provide a final working sample with/without await/async? I'm mocking I'm using Promises and this simple bit of code is throwing an error on the
Docs: https://jestjs.io/docs/en/mock-function-api#mockfnmockrejectedvaluevalue My test fails:
It seems that the instant that the Am I using it wrong? Sure seems like I'm following the docs. I'll post a full sample if someone can figure out what I'm doing wrong.
|
@jcollum try returning in front of your expect
If you don't return the expect when doing promises it doesn't resolve/ reject it for you |
The example in the docs tells you to |
Actually the issue was that the code under test didn't have a Complete test:
It would read cleaner with |
As long as you it('rejects gracefully if http call fails', async () => {
const msg = 'OMG EXPLOSIONS';
expect(fetch).toHaveBeenCalledTimes(0);
fetch.mockRejectedValueOnce(new Error(msg));
await expect(() =>
getArticle({
msgBody: {
collectionGroupId: '1',
id: '2',
marketplace: 'abc',
language: 'en',
cmsPath: 'http://test.com'
}
})
).rejects.toThrow(msg);
expect(fetch).toHaveBeenCalledTimes(1);
}); |
@SimenB You are certainly correct about not needing In Jest 23.0.1:
On the other hand, this works:
|
@jcollum the catch is needed because you are configuring a test dependency to return a rejected promise which causes your function under test to reject (1). You don't need the done and you can do
For the async awaiters around these parts you can achieve the same thing you just don't want the async function of the test to return a rejected promise or else jest will fail the test (1). We want to catch that it would fail and do an assertion that way the test still passes (2). When catching you are handling the error and a non reject promise is returned
|
Thanks for the input. |
For anyone having trouble parsing the content of this thread, the following is how you do it: await expect(repo.get(999)).rejects.toThrow(NotFoundException); |
Here's how I'm dealing with this in the event that I want to assert on properties of the error:
|
For anyone looking for a simple, working example of the problem posed in the original post: test('example', async () => {
async function fn() {
throw new Error('some error')
}
await expect(fn()).rejects.toThrow('some error')
}) |
This documentation example is still misleading (as mentioned above in 2017):
If
The example only works if the function throws a string instead of an Error, which is not a great assumption for the documentation to make. What works is to replace
|
@robertpenner your final example only tests whether an const fn = () => Promise.reject('expected message')
await expect(fn()).rejects.toThrow('expected message') // matches
await expect(fn()).rejects.toThrow('wrong message') // matches, though it shouldn't I believe the |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
jest version: 20.0.3
For sync method, it works in this way.
toThrowError
doesn't work with promises.I am getting an error:
This works! The async function throws a function that throws an error.
Obiously it doesn't make sense. I can see this line in the source code.
https://github.com/facebook/jest/pull/3068/files#diff-5d7e608b44e8080e7491366117a2025fR25
It should be
Promise.reject(new Error())
instead ofPromise.reject(() => {throw new Error();}
The example from the docs also doesn't work
The text was updated successfully, but these errors were encountered: