jest: Programatically fail a test
In the jest docs it mentions an example in the async tutorial
// Or try-catch.
it('tests error with async/await', async () => {
try {
await user.getUserName(2);
} catch (object) {
expect(object.error).toEqual('User with 2 not found.');
}
});
I think that this code should be written like this:
// Or try-catch.
it('tests error with async/await', async () => {
try {
await user.getUserName(2);
fail();
} catch (object) {
expect(object.error).toEqual('User with 2 not found.');
}
});
The fail()
will prevent the test from passing if getUserName()
does not throw an error.
However, I see no mention of the fail()
command anywhere in the docs, is this a supported API?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 32
- Comments: 20 (6 by maintainers)
Somehow this is not documented, but since Jest uses Jasmin this is possible:
The problem with your method is that if the promise resolves then the test will pass even though you expect it to reject.
The test should fail if the promise resolves. It should only pass if it rejects with the exact error that you expected.
You can also call
done.fail()
afterdone()
has been called. This is important if you want to fail conditionally when a specific thing happens.For example I wanted any call to
console.error
to trigger an exception and fail the test in question:In case anyone else comes across this, the global function
fail
works. I believe it’s a feature of Jasmine.That will stop working at some point - it’s not part of Jest’s documented API.
Also, any reason why you aren’t using this?
This is the idiomatic example from the docs:
So related to this, I’m currently trying to force my Jest tests to fail if
console.error
orconsole.warn
is called. Unfortunately, the only reliable way I’ve found to do so is to usefail()
:Raising an error does not work reliably when dealing with asynchronous React code, unfortunately. Does anyone have any thoughts on how this could be made to work without resort to
fail()
?It does look like using
expect.assertions(Infinity)
works, but that certainly seems like an abuse of the intent ofexpect.assertions
.I’m not sure if it’s possible to do with async/await syntax, I didn’t play with it much to be honest.
But maybe we could introduce a new matcher e.g.
.toBeRejected(object | string)
?Then you could test the case like this:
I’m not sure if we want to have a function like this.
fail()
as you proposed here will also prevent the test from passing ifgetUserName()
doesn’t throw and returns instantly.Instead you could test if
getUserName
function throws with e.g..toThrow()
method: http://facebook.github.io/jest/docs/api.html#tothrowIf you want to test Promise rejection, you can still go on with something like this:
There are plenty of ways, I just don’t see the reason to add another one.
No,
expect.assertions(1);
will fail the test if no assertion is runThis feature is also useful in case you are programmatically generating
test
/it
blocks based on async code. For example reading a text file -avoiding readSync- to assert something for each line.As the
describe
doesn’t allow the callback to return a promise (#2235), you cannot generate manyits
. So the solution is to use abeforeAll
for the async code. Then you can only have a singleit/test
for the whole file. So, if an expect fails, the error won’t be verbose enough to understand the error (which line failed) It is then cool to have a way to make it fail with a custom message.Here is my example.
done.fail()
worked but an out-of-the-boxfail()
would get rid of thedone()
. Also having a custom message forexpect()
could have done it.