Mock Network Latency Distributions in Axios

Mocking network latency distributions in Axios testing allows developers to simulate realistic, unpredictable network conditions—such as jitter, tail latency (p95/p99), and timeouts—rather than relying on static delay values. By integrating statistical distribution models into tools like Axios interceptors, axios-mock-adapter, or Mock Service Worker (MSW), teams can rigorously validate how client-side applications handle race conditions, loading states, retry policies, and slow connections.

1. Define the Latency Distribution Model

Real-world network requests do not have fixed response times. Instead, latency typically follows statistical distributions:

Here is a mathematical helper for generating sample distributions in JavaScript:

// Log-normal distribution generator
function getLogNormalDelay(meanMs, stdevMs) {
  const variance = stdevMs ** 2;
  const mu = Math.log((meanMs ** 2) / Math.sqrt(variance + meanMs ** 2));
  const sigma = Math.sqrt(Math.log(variance / (meanMs ** 2) + 1));
  
  // Box-Muller transform for normal random variable
  const u1 = Math.random();
  const u2 = Math.random();
  const z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2);
  
  return Math.exp(mu + sigma * z0);
}

2. Implement Latency Simulation in Axios

Approach A: Using Custom Axios Interceptors

Axios interceptors provide a native, dependency-free way to intercept requests or responses and insert artificial, distributed delays.

import axios from 'axios';

const api = axios.create({ baseURL: 'https://api.example.com' });

api.interceptors.response.use(async (response) => {
  if (process.env.NODE_ENV === 'test') {
    // Generate a delay from a log-normal distribution (mean: 200ms, stdev: 50ms)
    const delay = getLogNormalDelay(200, 50);
    await new Promise((resolve) => setTimeout(resolve, delay));
  }
  return response;
});

Approach B: Using axios-mock-adapter

When testing without a real backend, axios-mock-adapter allows dynamic handlers that resolve after a computed delay.

import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';

const mock = new MockAdapter(axios);

mock.onGet('/users').reply(async () => {
  const delay = getLogNormalDelay(150, 40);
  await new Promise((resolve) => setTimeout(resolve, delay));
  
  return [200, [{ id: 1, name: 'Alice' }]];
});

Approach C: Using Mock Service Worker (MSW)

MSW intercepts requests at the network level and provides a dedicated delay utility that accepts variable values.

import { http, HttpResponse, delay } from 'msw';

export const handlers = [
  http.get('https://api.example.com/users', async () => {
    const dynamicDelay = getLogNormalDelay(300, 100);
    await delay(dynamicDelay);
    
    return HttpResponse.json([{ id: 1, name: 'Alice' }]);
  }),
];

3. Testing Real-World Scenarios

Once variable latency is integrated into the test environment, configure test suites to evaluate specific resilience behaviors: