I am trying to test the rejection of one of my axios request call using moxios and jest. The method invoke (calling axios.get) throws error but catch block is not invoked.
My test code snippet is shown below,
it('should call errorHandler method when request is rejected', done => {
const errorResp = {
status: 400,
response: {message: 'invalid data'}
};
let mockFunction = jest.fn();
Axios.getRaw('/test').then(mockFunction);
moxios.wait(async () => {
let req = moxios.requests.mostRecent();
try {
let rejection = await req.reject(errorResp);
console.log('rejection', rejection);// rejection is undefined
done();
} catch (e) {
console.log(e);
// test assertions
done(e);
}
})
});
getRaw method,
const API_WRAPPER = TryCatchHandler.genericTryCatch;
export default {
getRaw: path => API_WRAPPER(axios.get(`${SERVER_DOMAIN}${path}`)),
}
API_WRAPPER method,
export default {
genericTryCatch: async (executionMethod) => {
try {
const response = await executionMethod;
return response;
} catch (error) {
return ApiError.errorHandler(error);
}
}
}
errorHandler method,
export default {
errorHandler: error => {
const {status} = error;
switch (status) {
case 400:
case 401:
case 403:
case 404:
case 409:
case 417:
case 500:
case 502:
console.log("Error Handler says:", error);
return error.response.data;
default:
console.log("Error Handler says:", error);
let errorObj = {
errorMsg: error.message,
stack: error.stack
};
return errorObj;
}
}
}
As the catch block is not invoked I am not able to assert my test cases. How do I get the catch invoked?
There are two things that should be pointed out about the code you provided.
In the first place, you should take into account that all the requests made with Axios.getRaw
are being wrapped with API_WRAPPER
. In the case the request results in an error the API_WRAPPER
is returning the result of processing the error (through the errorHandler
method).
Therefore, calling Axios.getRaw
will never execute any catch
statement present in the call:
Axios.getRaw('/test').then(function() {
// The code inside this method will always be executed, even when the request fails.
}).catch(function() {
// The code inside this method will never be executed.
});
In the case of a 400 error (the error you are testing in your test), the errorHandler
method is returning the value of error.response.data
. But in your test, the error you are creating does not have the data
attribute:
const errorResp = {
status: 400,
response: {message: 'invalid data'}
};
So, in order to get some meaningful data in your test, you should add the data
attribute with some value.
In the second place, I think you are not properly using the moxios
library. You are obtaining the most recent request and then you are awaiting for the result of the rejection:
let rejection = await req.reject(errorResp);
console.log('rejection', rejection);// rejection is undefined
But calling req.reject
does not return a promise (in fact, it does not return anything, that's why you are seeing an undefined
in your console.log
statement). You should wait for your original Axios.getRaw
promise to resolve.
Having that in mind you can rewrite your test like this:
it('should call errorHandler method when request is rejected', function(done) {
const errorResp = {
status: 400,
response: { message: 'invalid data', data: 'invalid data' }
};
// Store the promise so that we can wait for it to finish once we call the moxios reject method.
const promise = Axios.getRaw('/test');
moxios.wait(async function() {
let req = moxios.requests.mostRecent();
req.reject(errorResp);
// As your code does not generate an error in a 400 failed request, we use the then method.
promise.then(function(err) {
// In a 400 error, the err.response.data is returned as the response.
expect(err).toBe('invalid data');
done();
});
});
});
Hope this helps!