I'm testing a component that calls an API to populate a table with data. Though axios is used, axios is being wrapped in a convenience method of sorts to populate headers before executing the request via interceptors. I've tried axios-mock-adapter, but it's not working. I'm still new to testing React and I'm lost on how to mock data coming back from the api/axios. How do I go about mocking the api call to mock the data for my tests to pass??
This is my simple test:
test('<EmailTable/> ', async () => {
const { debug, getByText } = render(<CommunicationEmail />);
await waitFor(() => expect(getByText('Test Email Subject')).toBeTruthy());
}
This is the axios wrapper (api.js):
const instance = axios.create({
baseURL: `${apiUrl}/v1`,
timeout: 12000,
withCredentials: true,
headers: headers,
});
//intercept requests to validate hashed auth token
instance.interceptors.request.use((request) => {
const token = request.headers['X-Our-Access-Token'];
if (
localStorage.getItem('user_token') == null ||
SHA256(token).toString(enc.Hex) == localStorage.getItem('user_token')
) {
return request;
} else {
console.log({ what: 'Auth key invalid' });
return Promise.reject('Invalid token!');
}
});
//intercept responses to handle 401 errors
instance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
// handle 401 authentication errors and redirect to SSO
if (error.response != null && error.response.status != null && error.response.status === 401) {
console.error({ what: 'Authorization error', e: error });
}
return Promise.reject(error);
}
);
export default instance;
And here's a simplification of the component I'm trying to test:
import api from './api.js';
const EmailTable = () => {
const [emails, setEmails] = useState();
useEffect(() => {
if(!emails) {
getEmails();
}
}, [emails]);
const getEmails = async () => {
await api({
method: 'GET',
url: `/communications/emails`,
}).then((response) => {
if (response.success) {
setEmails(response.emails);
}
}
}
if(!emails) { return <div> Loading... </div> };
return <div>{emails}</div>;
}
UPDATE WITH SOLUTION:
To mock the axios wrapper that is my API, I had to mock the api module and return a resolved promise like so:
jest.mock('../api', () => {
return function (request) {
// If we want to mock out responses to multiple API requests, we could do if (request.url = "/blah/blah") { return new Promise.... }
return new Promise((resolve) => {
resolve({
data: { success: true, emails: [] },
});
});
};
});