4.1 Testing Error throws
In library or shared code, throwing errors can be useful to enforce an interface for a function for example.
This code should be tested, which can be challenging and differs based on the type of code under test.
This section tackles detection of throw
-ing a JavaScript error in a synchronous and an asynchronous context.
Check a synchronous function throws using the .toThrow
Jest matcher
Given a function that doesn’t throw like noError
as follows.
function noError() {
return 'success';
}
We can write a test asserting it doesn’t throw using expect().not.toThrow()
test('should not throw', () => {
expect(throws.bind(null)).not.toThrow(
new Error('throwing')
);
});
The test passes since the code under test doesn’t throw, but this time we get a Received function did not throw
error, which is maybe more descriptive and shows the advantage of using the Jest .toThrow
matcher.
npx jest src/04.01-no-throw.test.js
PASS src/04.01-no-throw.test.js
✓ should throw if passed true (3ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Say we have a function that throws:
function throws() {
throw new Error('throwing')
}
We can check that it throws with expect().toThrow(error)
.
test('should throw if passed true', () => {
expect(throws.bind(null)).toThrow(
new Error('throwing')
);
});
This test is passing since the function throws as we have asserted.
npx jest src/04.01-throws.test.js
PASS src/04.01-throws.test.js
✓ should throw if passed true (5ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Check an async function throws using expect().rejects.toEqual
The idiomatic Jest way to check an async
function throws is to use the await
or return
an expect(fn(param1)).rejects.toEqual(error)
.
Note: make sure to
await
orreturn
theexpect()
expression, otherwise Jest might not see the error as a failure but anUnHandledPromiseRejection
async function asyncThrowOrNot() {
throw new Error('async-throw')
}
test('should throw return expect()', async () => {
return expect(asyncThrowOrNot()).rejects.toEqual(
new Error('async-throw')
);
});
test('should throw await expect()', async () => {
await expect(asyncThrowOrNot()).rejects.toEqual(
new Error('async-throw')
);
});
These tests pass on async throw
’s as expected, as per the following output.
npx jest src/04.01-async-throw.test.js
PASS src/04.01-async-throw.test.js
✓ should throw return expect() (3ms)
✓ should throw await expect() (1ms)
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
This section showed how one might test test that’s designed to throw, both in the synchronous and the asynchronous case.
The next section tackles mocking the output of stubbed sync and async functions with Jest.