9

I am using axios.create method to create and configure axios instance. And I can't get it to work in tests with vi.fn() so I cannot assert if endpoint was called.

workaround for tests to be able to return data from api calls looks like

  return {
    AxiosInstance: {},
    AxiosRequestConfig: {},
    default: {
      post: vi.fn(),
      create: vi.fn(() => {
        return {
          post: (url: string, config: object) => {
            return Promise.resolve({ status: 200 });
          },
          get: (url: string, config: object) => {
            return Promise.resolve({ status: 200 });
          },
          interceptors: {
            request: {
              use: vi.fn(),
              eject: vi.fn(),
            },
            response: {
              use: vi.fn(),
              eject: vi.fn(),
            },
          },
        };
      }),
    },
  };
});

But would like to use something like

    (axios.get as MockedFunction<typeof axios.get>).mockImplementationOnce(
      () => promise
    );

maybe someone mocked axios.create using vitest and could share configuration?

3 Answers 3

11

So sorted it out, maybe it will help someone.

vi.mock('axios', () => {
  return {
    default: {
      post: vi.fn(),
      get: vi.fn(),
      delete: vi.fn(),
      put: vi.fn(),
      create: vi.fn().mockReturnThis(),
      interceptors: {
        request: {
          use: vi.fn(),
          eject: vi.fn(),
        },
        response: {
          use: vi.fn(),
          eject: vi.fn(),
        },
      },
    },
  };
});

so basically we mock axios.create method to return itself and we can write mocking like this

    (axios.post as MockedFunction<typeof axios.post>).mockResolvedValue(
      () => Promise.resolve({ status: 200 })
    );
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I had a nightmare understanding my mocking issue (mocked axios was undefined) was coming from the create method - and mocking it is tough. You saved my day
8

If, for instance, you're using axios.create() in your codebase to generate an AxiosInstance, you can mock this functionality as follows in your Vitest test file:

const mocks = vi.hoisted(() => ({
  get: vi.fn(),
  post: vi.fn(),
}));

vi.mock('axios', async(importActual) => {
  const actual = await importActual<typeof import ('axios')>();

  const mockAxios = {
    default: {
      ...actual.default,
      create: vi.fn(() => ({
        ...actual.default.create(),
        get: mocks.get,
        post: mocks.post,
      })),
    },
  };

  return mockAxios;
});

Initially, we set up the mocks object that includes the get and post functions we want to mock. Using vi.hoisted(), we ensure these mocked functions are hoisted (i.e., moved to the top of the scope), allowing us to reference them within our vi.mock() function.

Then, we mock the entire axios module using vi.mock(). In order to maintain the existing functionality that we don't intend to mock, we employ importActual to import the real axios module. We then specify the parts we wish to mock, namely the create function and the get/post functions.

With these mocks in place, we can now spy on our mocked get and post methods. Here's an example of how to do it:

it('should call axios.get', async() => {
  mocks.get.mockResolvedValueOnce({
    data: {},
  });
  await api.getFromAPI();
  expect(mocks.get).toHaveBeenCalled(); // should return true
});

In the test case, we mock a resolved value for our get method and call the function we want to test (api.getFromAPI() in this case). We then check whether our mocked get function has been called using expect().toHaveBeenCalled().

This setup provides a controlled environment to test the interactions with the axios library in our code.

1 Comment

Please do not post the same answer to more than one question. Also, do not post ChatGPT answers, because they are plagiarism violating the Code of Conduct and officially BANNED on Stack Overflow](meta.stackoverflow.com/q/421831). Please read: Why posting GPT and ChatGPT generated answers is not currently allowed.
1

If you can export the object axios.create returns and use it in your project instead of using axios directly, then you can simply use vi.spyOn.

src file

...

export const api = axios.create(...);

...

test file

...

vi.spyOn(api, 'get').mockResolvedValue(...)

...

1 Comment

Thank you. It's the simplest solution that works for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.