How to Mock Network Latency in Axios Tests
Testing how applications handle slow network connections and loading
states is essential for building resilient user interfaces. This article
covers practical techniques to mock network latency when testing HTTP
requests with Axios. You will learn how to introduce artificial delays
using popular mocking libraries like axios-mock-adapter and
Mock Service Worker (MSW), as well as how to implement custom delay
interceptors for unit and integration tests.
1. Using
axios-mock-adapter
The most straightforward way to simulate network latency with Axios
is using the axios-mock-adapter library. It provides a
built-in delayResponse configuration option that defers the
mock response resolution by a specified number of milliseconds.
Installation
npm install --save-dev axios-mock-adapterImplementation
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
describe('API Latency Tests', () => {
let mock;
beforeEach(() => {
// Initialize mock adapter with a 1500ms delay
mock = new MockAdapter(axios, { delayResponse: 1500 });
});
afterEach(() => {
mock.restore();
});
it('handles slow response correctly', async () => {
mock.onGet('/api/users').reply(200, [{ id: 1, name: 'Alice' }]);
const startTime = Date.now();
const response = await axios.get('/api/users');
const duration = Date.now() - startTime;
expect(response.status).toBe(200);
expect(duration).toBeGreaterThanOrEqual(1500);
expect(response.data).toEqual([{ id: 1, name: 'Alice' }]);
});
});2. Using Custom Axios Interceptors
If you prefer not to install extra dependencies, you can use Axios response interceptors to inject custom delay logic into your test environment.
Implementation
import axios from 'axios';
// Helper function to introduce delay
const createDelayInterceptor = (delayMs) => {
return async (response) => {
await new Promise((resolve) => setTimeout(resolve, delayMs));
return response;
};
};
describe('Axios Interceptor Delay', () => {
let interceptorId;
beforeEach(() => {
// Add latency to all responses
interceptorId = axios.interceptors.response.use(
createDelayInterceptor(1000)
);
});
afterEach(() => {
// Eject interceptor to clean up
axios.interceptors.response.eject(interceptorId);
});
it('delays response via interceptor', async () => {
const start = Date.now();
const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
const elapsed = Date.now() - start;
expect(elapsed).toBeGreaterThanOrEqual(1000);
expect(response.status).toBe(200);
});
});3. Using Mock Service Worker (MSW)
Mock Service Worker (MSW) intercepts requests at the network level
and includes a native delay() utility to simulate realistic
network latency across testing environments.
Installation
npm install --save-dev mswImplementation
import axios from 'axios';
import { http, HttpResponse, delay } from 'msw';
import { setupServer } from 'msw/node';
const server = setupServer(
http.get('/api/data', async () => {
// Add artificial network delay of 2000ms
await delay(2000);
return HttpResponse.json({ message: 'Success' });
})
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
it('simulates slow endpoint using MSW', async () => {
const start = Date.now();
const response = await axios.get('/api/data');
const duration = Date.now() - start;
expect(response.data).toEqual({ message: 'Success' });
expect(duration).toBeGreaterThanOrEqual(2000);
});Testing Timeouts and UI Loading States
Mocking network latency is particularly useful for verifying UI loading indicators and handling request timeouts.
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
it('triggers an Axios timeout error when latency exceeds timeout limit', async () => {
const mock = new MockAdapter(axios, { delayResponse: 3000 });
mock.onGet('/api/slow-endpoint').reply(200);
const client = axios.create({
timeout: 1000, // 1-second timeout
});
await expect(client.get('/api/slow-endpoint')).rejects.toThrow('timeout of 1000ms exceeded');
mock.restore();
});