jest-mock-axios
jest-mock-axios copied to clipboard
UnhandledPromiseRejection when returing `Promise.reject` on interceptor
I'm trying to test my interceptor logic, whether calling the error reporter (like Sentry), showing toast error, and resetting the auth state if we received a 401 response from our server. The problem that we're facing is that we got the following error every time we ran the test:
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "AxiosError".]
{
code: 'ERR_UNHANDLED_REJECTION'
}
Based on Interceptors Docs we need to return a rejected promise on the second parameter (onRejected) for the interceptor, but when I remove the Promise.reject
calls (just returning the error), the test successfully ran.
But that turns out to break my app.
Additional info that might help
- Stackblitz to reproduce https://stackblitz.com/edit/node-wsmxdh?file=index.test.ts
Any idea how I test my interceptor logic without breaking my app? Thanks in advance!
Hi,
thanks for raising this issue. You're right, response interceptors returning a promise are not correctly handled at the moment. I'll fix this.
Hi,
I published 4.7.0-beta
on npm. This should fix the UnhandledPromiseRejection
at least and make the test work. Can you install this version and try if it works?
This still does not implement correct interceptor behavior, as the result of the onRejected
handler is discarded in any case. However, for the moment this might be enough.
Hi @kingjan1999. I've installed the 4.7.0-beta
and it works. Thanks!
Hello, I am also trying to test response interceptors. My test is expecting the function-under-test to throw an error, which is what I believe Promise.reject
normally does, and it is failing because no error is being thrown. This is happening with 4.7.0-beta
If I'm testing it incorrectly, please let me know, but here is what I'm doing:
it('will throw unauthorized if the status is 401', async () => {
await expect(() => {
const promise = service.getTheThing()
mockAxios.mockError({ response: { status: 401, data: {} }})
return promise
}).rejects.toThrow(UnauthorizedError)
})
The interceptors:
axios.interceptors.response.use((response) => {
return response
}, (error: AxiosError) => {
if (error?.response?.status) {
// This function just returns the appropriate error object to be thrown by Promise.reject()
return Promise.reject(this.checkExceptionForStatus(error))
}
return Promise.reject(error)
})
@rosstroha I think you stumbled about the behavior I described above with "interceptors are not corrected properly".
The current implementation in 4.7.0-beta
just avoids the error being unhandled completely, but it does not handle it properly whatsoever. I'll fix this before releasing 4.7.0
, once I've found out why this isn't working at the moment.
@rosstroha I think you stumbled about the behavior I described above with "interceptors are not corrected properly".
The current implementation in
4.7.0-beta
just avoids the error being unhandled completely, but it does not handle it properly whatsoever. I'll fix this before releasing4.7.0
, once I've found out why this isn't working at the moment.
Fair enough :) Thank you @kingjan1999!