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