Mocking Axios Requests with MSW and Axios Mock Adapter
Mocking Axios HTTP requests is a fundamental practice in modern
JavaScript and TypeScript development for creating reliable, fast, and
deterministic tests. This article demonstrates how to intercept and
simulate network calls using two prominent solutions:
axios-mock-adapter, an Axios-specific mocking tool, and
Mock Service Worker (MSW), an API mocking library that intercepts
requests at the network level. You will learn the setup, implementation,
and best practices for both approaches in testing environments such as
Jest or Vitest.
Method 1: Mocking with
axios-mock-adapter
axios-mock-adapter allows you to wrap an Axios instance
and define mock responses for specific request paths, HTTP methods, and
parameters. It works directly inside the Axios request pipeline.
1. Installation
npm install axios-mock-adapter --save-dev2. Basic Implementation
Consider an API module that fetches user details:
// api.js
import axios from 'axios';
export const fetchUser = async (userId) => {
const response = await axios.get(`/api/users/${userId}`);
return response.data;
};You can test this function by attaching MockAdapter to
the default or custom Axios instance:
// api.test.js
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { fetchUser } from './api';
describe('fetchUser with axios-mock-adapter', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
it('fetches user successfully', async () => {
const mockData = { id: 1, name: 'Jane Doe' };
// Define the mock behavior
mock.onGet('/api/users/1').reply(200, mockData);
const result = await fetchUser(1);
expect(result).toEqual(mockData);
});
it('handles 404 errors', async () => {
mock.onGet('/api/users/99').reply(404);
await expect(fetchUser(99)).rejects.toThrow();
});
});Key Features of
axios-mock-adapter:
replyOnce(): Return a response only for the first matching request.onGet(path, { params }): Match requests based on query parameters.mock.reset(): Clear defined mock handlers while keeping the adapter attached.mock.restore(): Completely remove the mock adapter and restore the original Axios instance.
Method 2: Mocking with Mock Service Worker (MSW)
MSW intercepts requests at the network level using the
fetch interceptor or Service Workers, making your tests
client-agnostic. This means your mocks will continue to work even if you
replace Axios with another client like native fetch.
1. Installation
npm install msw --save-dev2. Basic Implementation (Node/Jest/Vitest Environment)
Step A: Define Request Handlers
// mocks/handlers.js
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('https://api.example.com/users/:id', ({ params }) => {
const { id } = params;
if (id === '1') {
return HttpResponse.json({ id: 1, name: 'Jane Doe' }, { status: 200 });
}
return new HttpResponse(null, { status: 404 });
}),
];Step B: Set Up the Test Server
// mocks/server.js
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
export const server = setupServer(...handlers);Step C: Integrate Server into Test Lifecycle
// api.test.js
import axios from 'axios';
import { server } from './mocks/server';
import { http, HttpResponse } from 'msw';
// Lifecycle setup for MSW
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
const fetchUser = async (id) => {
const response = await axios.get(`https://api.example.com/users/${id}`);
return response.data;
};
describe('fetchUser with MSW', () => {
it('returns user data for valid id', async () => {
const data = await fetchUser(1);
expect(data).toEqual({ id: 1, name: 'Jane Doe' });
});
it('handles server errors via runtime overrides', async () => {
// Override handler for this specific test case
server.use(
http.get('https://api.example.com/users/1', () => {
return new HttpResponse(null, { status: 500 });
})
);
await expect(fetchUser(1)).rejects.toThrow();
});
});Comparing
axios-mock-adapter and MSW
| Feature | axios-mock-adapter |
MSW (Mock Service Worker) |
|---|---|---|
| Interception Level | Axios instance level | Network level (Interceptors/Service Worker) |
| Client Dependency | Bound exclusively to Axios | Client-agnostic (fetch,
Axios, GraphQL, etc.) |
| Setup Complexity | Low (minimal boilerplate) | Moderate (requires handler and server setup) |
| Browser Support | Yes (in-memory adapter) | Yes (via actual Service Workers) |
| Best For | Isolated unit tests using Axios directly | Integration tests, end-to-end setups, and cross-framework codebases |
Choosing the Right Tool
Use axios-mock-adapter when you have a
legacy or targeted codebase that relies solely on Axios, and you require
quick setup with minimal configuration. Choose MSW when
building modern, decoupled applications where network-level mocking,
adherence to web standards, and sharing mock definitions between unit
tests, development servers, and end-to-end tests are priorities.