最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Mocking axios.create using vitest - Stack Overflow

programmeradmin5浏览0评论

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?

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?

Share Improve this question asked Apr 21, 2023 at 9:59 IowAIowA 1,0562 gold badges14 silver badges27 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

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 })
    );

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.

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(...)

...
发布评论

评论列表(0)

  1. 暂无评论