How to Unit Test Axios transformResponse Functions
This article explains how to unit test custom
transformResponse functions in Axios to ensure incoming
HTTP response payloads are correctly parsed, normalized, or validated.
You will learn how to extract transformations into testable pure
functions, write direct unit tests using frameworks like Jest or Vitest,
and verify pipeline integration using mock adapters without making
actual network calls.
1. Understanding
transformResponse
Axios provides the transformResponse option to modify
response data before it is passed to then or
catch. The function receives two arguments: the raw
response data and the response headers. It is
expected to return the transformed data.
// Example transformer
function parseAndNormalizeDates(data, headers) {
if (typeof data !== 'string') {
return data;
}
try {
const parsed = JSON.parse(data);
if (parsed.createdAt) {
parsed.createdAt = new Date(parsed.createdAt);
}
return parsed;
} catch (error) {
return data;
}
}2. Strategy A: Unit Testing the Transformation Function in Isolation
The simplest and most maintainable approach is to separate the transformation logic from the Axios configuration and export it as an independent pure function.
Writing the Tests
You can test edge cases such as valid payloads, invalid JSON, missing properties, and custom header behaviors directly:
import { parseAndNormalizeDates } from './transformers';
describe('parseAndNormalizeDates', () => {
it('should parse valid JSON and convert createdAt to a Date object', () => {
const rawData = JSON.stringify({ id: 1, createdAt: '2023-01-01T00:00:00Z' });
const headers = { 'content-type': 'application/json' };
const result = parseAndNormalizeDates(rawData, headers);
expect(result.id).toBe(1);
expect(result.createdAt).toBeInstanceOf(Date);
expect(result.createdAt.toISOString()).toBe('2023-01-01T00:00:00.000Z');
});
it('should return raw data if JSON parsing fails', () => {
const malformedData = '{ invalid json }';
const headers = { 'content-type': 'application/json' };
const result = parseAndNormalizeDates(malformedData, headers);
expect(result).toBe(malformedData);
});
it('should return non-string data without modification', () => {
const objectData = { id: 2 };
const headers = {};
const result = parseAndNormalizeDates(objectData, headers);
expect(result).toEqual(objectData);
});
});3. Strategy B: Testing within an Axios Instance Pipeline
If you need to verify that Axios correctly applies the function
within its default transformation chain, test the transformer attached
to an Axios client instance using axios-mock-adapter.
Setting Up the Axios Client
// apiClient.js
import axios from 'axios';
import { parseAndNormalizeDates } from './transformers';
export const apiClient = axios.create({
baseURL: 'https://api.example.com',
transformResponse: [
...axios.defaults.transformResponse,
parseAndNormalizeDates
]
});Writing the Pipeline Unit Test
// apiClient.test.js
import MockAdapter from 'axios-mock-adapter';
import { apiClient } from './apiClient';
describe('apiClient transformResponse pipeline', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(apiClient);
});
afterEach(() => {
mock.restore();
});
it('transforms API response data through the full Axios request cycle', async () => {
const mockPayload = { id: 10, createdAt: '2024-05-15T12:00:00Z' };
mock.onGet('/users/10').reply(200, JSON.stringify(mockPayload), {
'content-type': 'application/json'
});
const response = await apiClient.get('/users/10');
expect(response.status).toBe(200);
expect(response.data.id).toBe(10);
expect(response.data.createdAt).toBeInstanceOf(Date);
});
});Best Practices
- Always preserve default transformations: When
chaining custom transformers, append them to
axios.defaults.transformResponseto avoid breaking Axios's built-in JSON parsing unless you intend to replace it completely. - Handle parse errors gracefully: Never let a transform function throw unhandled exceptions unless you want the entire request promise to reject immediately.
- Keep transformers pure: Avoid reading external
state, modifying global variables, or triggering side effects inside
transformResponse.