test('rejects unknown user', () => {
expect(service.findOne(999)).rejects.toThrow(NotFoundException);
});
it('loads the user', () => {
service.findOne(1).then((u) => {
expect(u.email).toBe('a@b.c');
});
});
Jest waits for a test only in two cases:
- The test function returns a promise. An
asyncfunction always does. - The test uses the
donecallback.
Here, each test creates a promise but does not return it or await it. So the function returns undefined, and Jest marks the test as passed. The assertion runs after the test has already finished. Its failure, at best, shows up as a stray error after the run or inside another test.
Fix: make the tests async and await the work.
- Write
await expect(service.findOne(999)).rejects.toThrow(NotFoundException). - Write
const u = await service.findOne(1)before you assert onu.
Returning the promise also works.
Lint rules catch this mistake:
valid-expectfrom eslint-plugin-jestvalid-expect-in-promisefrom eslint-plugin-jestno-floating-promisesfrom typescript-eslint
- Jest waits only for a returned promise or the done callback.
- If you don't return or await a promise, the test finishes before the assertion runs.
- Await (or return) the promise, and use .rejects or .resolves with await.
- Lint rules such as no-floating-promises catch this mistake.
Read more