I am testing an endpoint with JEST and Got. I expect 403 Forbidden error. The following code prints the error from catch block AND fails that the identical call does not throw an error. Why?
try {
response = await api(`verify/${profile.auth.verifyToken}`, {method: 'POST'}).json();
} catch (e) {
console.log(e);
}
expect(async () => {
response = await api(`verify/${profile.auth.verifyToken}`, {method: 'POST'}).json();
}).toThrow();
Output:
console.log test/api.int.test.js:112
HTTPError: Response code 403 (Forbidden)
at EventEmitter.<anonymous> (C:\dev\mezinamiridici\infrastructure\node_modules\got\dist\source\as-promise.js:118:31)
at processTicksAndRejections (internal/process/task_queues.js:97:5) {
name: 'HTTPError'
}
Error: expect(received).toThrow()
Received function did not throw
This variant does not work either:
expect(() => api(`verify/${profile.auth.verifyToken}`, {method: 'POST'})).toThrow();
Btw when the HTTPError is thrown and not catched, there is no stacktrace and I do not see where the error was thrown. If there are other error I exactly see which test line was responsible. Why?
expect(...).toThrow()
is for checking if an error is thrown from a function call. When calling an async function, it never throws an error; rather it returns a Promise
which may eventually become "rejected." Although async functions use the same throw
/catch
terminology, the code required to detect a thrown error differs from what's required to detect a rejected Promise. This is why Jest needs a different assertion technique.
Try expect(...).rejects.toThrow()
instead:
await expect(() => api(`verify/${profile.auth.verifyToken}`, {method: 'POST'}).json())
.rejects.toThrow();
Notice you have to await
this assertion because Jest needs to wait until the Promise
finalizes before seeing whether it resolved or rejected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With