我目前正在开发一个使用 React 和 Axios 发出 HTTP 请求的项目。在本地开发环境中,我想模拟这些请求以避免触及实际的 API。我已经设置了一些条件逻辑来检查代码是否在开发模式下运行,如果为真则模拟请求
if (process.env.NODE_ENV === 'development') {
// Mocking Axios in development mode
axios.interceptors.request.use(request => {
if (request.url === '/api/data') {
return Promise.resolve({ data: 'mock data' });
}
return request;
});
}
虽然这有效,但我想要一个更干净、更可维护的解决方案,以将模拟逻辑与主应用程序代码分开。
我尝试使用 Axios 拦截器基于 NODE_ENV 环境变量来模拟请求。这可行,但我必须检查每个请求的路径,这使代码变得混乱。我正在寻找一种解决方案,将所有这些都排除在我的生产应用程序的代码之外。
axios-mock-adapter
来轻松模拟请求。下面的示例使用 Vite
和 React
。通过 import.meta.env.MODE === 'development'
检查环境,然后设置模拟。
App.tsx
:
import { useEffect, useState } from 'react';
import { axiosInstance } from './axiosInstance';
function App() {
const [todo, setTodo] = useState<{ title: string }>();
const [user, setUser] = useState<{ username: string }>();
useEffect(() => {
axiosInstance.get('/todos/1').then((res) => setTodo(res.data));
axiosInstance.get('/users/1').then((res) => setUser(res.data));
}, []);
return (
<>
<p>title: {todo?.title}</p>
<p>username: {user?.username}</p>
</>
);
}
export default App;
axiosInstance.ts
:
import axios from 'axios';
export const axiosInstance = axios.create({
baseURL: 'https://jsonplaceholder.typicode.com',
});
main.tsx
:
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App.tsx';
import { axiosInstance } from './axiosInstance';
import mocks from './mocks';
if (import.meta.env.MODE === 'development') {
console.log('setup mock');
const MockAdapter = (await import('axios-mock-adapter')).default;
const mock = new MockAdapter(axiosInstance);
mocks.todosAPI(mock);
mocks.usersAPI(mock);
}
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>
);
./mocks/todos.ts
:
import MockAdapter from 'axios-mock-adapter';
export const todosAPI = (mock: MockAdapter) => {
mock.onGet('/todos/1').reply(200, {
userId: 1,
id: 1,
title: 'fake todo title 1',
completed: false,
});
};
./mocks/users.ts
:
import MockAdapter from 'axios-mock-adapter';
export const usersAPI = (mock: MockAdapter) => {
mock.onGet('/users/1').reply(200, {
id: 1,
name: 'fake name',
username: 'fake username',
email: '[email protected]',
});
};