I've found a lot of this sort of thing when refactoring our Jest test suites:
it('calls the API and throws an error', async () => {
expect.assertions(2);
try {
await login('email', 'password');
} catch (error) {
expect(error.name).toEqual('Unauthorized');
expect(error.status).toEqual(401);
}
});
I believe the expect.assertions(2)
line is redundant here, and can safely be removed, because we already await
the async call to login()
.
Am I correct, or have I misunderstood how expect.assertions
works?
expect.assertions
is important when testing the error scenarios of asynchronous code, and is not redundant.
If you remove expect.assertions
from your example you can't be confident that login
did in fact throw the error.
it('calls the API and throws an error', async () => {
try {
await login('email', 'password');
} catch (error) {
expect(error.name).toEqual('Unauthorized');
expect(error.status).toEqual(401);
}
});
Let's say someone changes the behavior of login
to throw an error based on some other logic, or someone has affected the mock for this test which no longer causes login
to throw. The assertions in the catch
block won't run but the test will still pass.
Using expect.assertions
at the start of the test ensures that if the assertions inside the catch don't run, we get a failure.