如何使用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整个模块:
- 实例模块示例:
// 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;
- 测试文件中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
相关产品推荐
相关产品推荐

