Published 10 Jun, 2022

How to mock interceptors when using jest.mock('axios')?

Category React
Modified : Feb 01, 2023

React is a highly popular js library which makes writing frontend a breeze, it makes javascript make more sense by laying out UIs in components which acts and behaves independently. React is one of the go to libraries for modern web development.

There are 3 suggested solutions in this post and each one is listed below with a detailed description on the basis of most helpful answers as shared by the users. I have tried to cover all the aspects as briefly as possible covering topics such as Reactjs, Axios, Jestjs, React Testing Library and a few others. I have categorized the possible solutions in sections for a clear and precise explanation. Please consider going through all the sections to better understand the solutions.

Solution 1

This was enough in the end, plain and simple jest.fn()

jest.mock('axios', () => {
    return {
        interceptors: {
            request: { use: jest.fn(), eject: jest.fn() },
            response: { use: jest.fn(), eject: jest.fn() },
        },
    };
});

Solution 2

Make sure to mock out the interceptors and axios.create if used:

// Replace any instances with the mocked instance (a new mock could be used here instead):
axios.create.mockImplementation((config) => axios);

// Mock out the interceptor (assuming there is only one):
let requestCallback = () => {
  console.log("There were no interceptors");
};
axios.interceptors.request.use.mockImplementation((callback) => {
  requestCallback = callback;
});

// Mock out the get request so that it returns the mocked data but also calls the 
// interceptor code:
axios.get.mockImplementation(() => {
  requestCallback();
  return {
    data: "this is some data"
  };
});

Note if this doesn't work:

This example assumes that the create and interceptor calls are in a place where Jest can mock them out. Placing the axios.create or axiosInstance.interceptors.request.use lines outside the scope of the function may cause the above mocking to fail. This is an example file where Jest can mock them out:

const axios = require('axios');

const DEBUG = true;

const customRequest = (url) => {
  // Example of axios.create from https://www.npmjs.com/package/axios#axioscreateconfig
  const axiosInstance = axios.create({
    baseURL: 'https://some-domain.com/api/',
    timeout: 1000,
    headers: {'X-Custom-Header': 'foobar'}
  });

  // Example of interceptor taken from https://stackoverflow.com/a/52737325/7470360:
  axiosInstance.interceptors.request.use((config) => {
    if (DEBUG) { console.info("Request called", config); }
    return config;
  }, (error) => {
    if (DEBUG) { console.error("Request error ", error); }
    return Promise.reject(error);
  });

  return axiosInstance.get(url);
}

module.exports = customRequest;

The mocking code will mock out the axios.create call and the axiosInstance calls in customRequest. Moving either the creation or interception outside the function will cause the mocks to fail.


Solution 3

Here's the final solution you can try out in case no other solution was helpful to you. This one's applicable and useful in some cases and could possiblty be of some help. No worries if you're unsure about it but I'd recommend going through it.

Here is how I mocked axios.create and its interceptors:

jest.mock('axios', () => {
  return {
    create: () => {
      return {
        interceptors: {
          request: ,
          response: ,
        },
      };
    },
  };
});

Afterwards I was able to call the following in my test code:

const client = axios.create({
  baseURL: 'http://some-url.com',
});

client.interceptors.request.use(config => {
  // some other test code
  return config;
});

Final Words

React has become the go to library for frontend development. It has a wide community support and a multitude of ready made components. These were few of the solutions reported helpful by the community. Hope it turns out helpful for you as well.

It works on my machine.
Unknown