You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Vitest模拟axios.create?求可行配置方案

如何在Vitest中简洁模拟axios.create创建的实例

我用axios.create创建并配置了axios实例,但在Vitest测试中没法用vi.fn()正常mock它,也没法断言API端点是否被调用。目前我用了比较繁琐的变通方案来让测试返回API数据:

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

但我希望能像下面这种简洁的方式实现mock:

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

有没有简洁的Vitest模拟axios.create的配置方法?


简洁模拟方案

场景1:将axios实例封装为单独模块

如果你的项目里把axios.create创建的实例封装成了单独模块(比如src/api/client.ts),可以直接mock整个模块:

  1. 实例模块示例:
// src/api/client.ts
import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://api.example.com',
  headers: { 'Content-Type': 'application/json' }
});

export default apiClient;
  1. 测试文件中mock该模块:
// src/api/client.test.ts
import { vi, expect, it } from 'vitest';
import apiClient from './client';

// 提前mock整个axios实例模块
vi.mock('./client', () => {
  const mockPost = vi.fn(() => Promise.resolve({ status: 200, data: {} }));
  const mockGet = vi.fn(() => Promise.resolve({ status: 200, data: {} }));
  return {
    default: {
      post: mockPost,
      get: mockGet,
      interceptors: {
        request: { use: vi.fn(), eject: vi.fn() },
        response: { use: vi.fn(), eject: vi.fn() }
      }
    }
  };
});

it('should call post endpoint correctly', async () => {
  const testData = { key: 'value' };
  await apiClient.post('/test', testData);

  // 断言post方法被调用,且参数正确
  expect(apiClient.post).toHaveBeenCalledWith('/test', testData);
});

单个测试中动态修改mock返回值:

it('should handle error response', async () => {
  (apiClient.post as MockedFunction<typeof apiClient.post>).mockImplementationOnce(() => 
    Promise.reject({ status: 400, data: { error: 'Bad Request' } })
  );

  await expect(apiClient.post('/error')).rejects.toMatchObject({ status: 400 });
});

场景2:直接在代码中创建axios实例

如果是在组件或函数内部直接调用axios.create,可以mockaxios包的create方法,让它返回带mock方法的实例:

// src/components/Example.test.ts
import { vi, expect, it } from 'vitest';
import axios from 'axios';
import ExampleComponent from './Example';

// mock axios的create方法
vi.mock('axios');
const mockAxiosInstance = {
  post: vi.fn(() => Promise.resolve({ status: 200 })),
  get: vi.fn(() => Promise.resolve({ status: 200 })),
  interceptors: {
    request: { use: vi.fn(), eject: vi.fn() },
    response: { use: vi.fn(), eject: vi.fn() }
  }
};
(axios.create as MockedFunction<typeof axios.create>).mockReturnValue(mockAxiosInstance);

it('should trigger API call on button click', async () => {
  // 渲染组件并触发操作(示例逻辑)
  // ...

  // 断言create被调用,且post方法被执行
  expect(axios.create).toHaveBeenCalled();
  expect(mockAxiosInstance.post).toHaveBeenCalledWith('/target-endpoint', expect.any(Object));
});

动态修改实例方法返回值:

it('should handle successful response', async () => {
  mockAxiosInstance.get.mockImplementationOnce(() => 
    Promise.resolve({ status: 200, data: { items: [] } })
  );

  // 执行测试逻辑
  // ...

  expect(mockAxiosInstance.get).toHaveBeenCalled();
});

内容的提问来源于stack exchange,提问作者IowA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 15:45:27