Mock Dynamic Axios Responses with Query Params
Mocking dynamic API responses based on query parameters in Axios
allows developers to test various application states, edge cases, and
pagination flows locally without relying on an active backend. This
guide demonstrates how to inspect incoming request parameters
dynamically and return customized responses using
axios-mock-adapter as well as native Axios custom
adapters.
Using axios-mock-adapter for Dynamic Responses
The standard and most flexible tool for mocking Axios requests is the
axios-mock-adapter library. It allows you to pass a
callback function to the .reply() method, exposing the
request configuration object (config), which contains the
query parameters.
1. Installation
Install the library in your project:
npm install axios-mock-adapter --save-dev2. Implementation
Attach the mock adapter to your Axios instance and inspect
config.params within the .reply()
callback:
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
// Create an Axios instance
const apiClient = axios.create({
baseURL: 'https://api.example.com',
});
// Initialize the mock adapter
const mock = new MockAdapter(apiClient);
// Mock a dynamic GET request based on query parameters
mock.onGet('/users').reply((config) => {
const { role, page = 1, limit = 10 } = config.params || {};
// Mock dataset
const users = [
{ id: 1, name: 'Alice', role: 'admin' },
{ id: 2, name: 'Bob', role: 'editor' },
{ id: 3, name: 'Charlie', role: 'admin' },
{ id: 4, name: 'David', role: 'viewer' },
];
// Filter based on query params
let filteredUsers = users;
if (role) {
filteredUsers = users.filter((user) => user.role === role);
}
// Handle pagination
const startIndex = (page - 1) * limit;
const paginatedUsers = filteredUsers.slice(startIndex, startIndex + Number(limit));
// Return status code and response payload
return [
200,
{
data: paginatedUsers,
total: filteredUsers.length,
page: Number(page),
},
];
});3. Making Requests
When making requests through the Axios instance, the adapter intercepts the call and serves data matching the passed query parameters:
async function fetchUsers() {
// Returns only admin users
const adminResponse = await apiClient.get('/users', {
params: { role: 'admin' },
});
console.log(adminResponse.data);
// Returns paginated results
const pagedResponse = await apiClient.get('/users', {
params: { page: 2, limit: 2 },
});
console.log(pagedResponse.data);
}
fetchUsers();Dynamic Matching
with params Matching Rules
axios-mock-adapter also supports defining specific
routes for exact parameter matches before falling back to a general
handler:
// Exact match for ?role=guest
mock.onGet('/users', { params: { role: 'guest' } }).reply(200, {
data: [],
message: 'No guests found',
});
// Fallback for any other /users query
mock.onGet('/users').reply(200, {
data: [{ id: 99, name: 'Default User' }],
});Alternative: Mocking via Custom Axios Adapter
If you prefer zero external dependencies, you can define a custom
adapter directly on your Axios configuration:
import axios from 'axios';
const mockAdapter = async (config) => {
const { url, params } = config;
if (url === '/products') {
const category = params?.category;
if (category === 'electronics') {
return {
data: [{ id: 101, name: 'Laptop' }],
status: 200,
statusText: 'OK',
headers: {},
config,
};
}
return {
data: [{ id: 201, name: 'Generic Item' }],
status: 200,
statusText: 'OK',
headers: {},
config,
};
}
return Promise.reject(new Error(`Unhandled route: ${url}`));
};
const api = axios.create({ adapter: mockAdapter });Simulating Errors and Latency
To build realistic tests, you can conditionally simulate HTTP errors or network delays based on query flags:
mock.onGet('/status').reply(async (config) => {
const { shouldFail, delay } = config.params || {};
if (delay) {
await new Promise((resolve) => setTimeout(resolve, Number(delay)));
}
if (shouldFail === 'true') {
return [500, { error: 'Internal Server Error' }];
}
return [200, { status: 'Operational' }];
});