1

I have the following axios file:

    /* eslint-disable no-param-reassign */
import axios from 'axios';
import { baseURL } from './apiClient';

export default function authenticatedApiClient(jwt: string) {
  const apiClient = axios.create({
    baseURL,
  });

  apiClient.interceptors.request.use((config) => {
    config.headers = config.headers || {};
    config.headers.Authorization = `Bearer ${jwt}`;
    return config;
  });

  return apiClient;
}

And the following test:

   import React from 'react';
import {
  act, render, screen,
} from '@testing-library/react';
import mockAxios from 'jest-mock-axios';
import { BrowserRouter } from 'react-router-dom';
import { AppProvider } from '../common/AppProvider';
import DisplayEditProfileForm from '.';

test('should render edit user profile form', async () => {
  const user = {
    username: 'admin',
    email: 'ad@ad.com',
  };
  act(() => {
    mockAxios.get.mockResolvedValueOnce({ data: user });
  });

  render(
    <BrowserRouter>
      <AppProvider>
        <DisplayEditProfileForm />
      </AppProvider>
    </BrowserRouter>,
  );

  const usernameInputLabel = screen.getByText(/Username/i);
  expect(usernameInputLabel).toBeInTheDocument();

  const emailInputLabel = screen.getByText(/Email/i);
  expect(emailInputLabel).toBeInTheDocument();

  const passwordConfirmationInputLabel = screen.getByText(/Password confirmation/i);
  expect(passwordConfirmationInputLabel).toBeInTheDocument();
});

We have recently implemented the interceptors, and now my tests throw the following error:

TypeError: Cannot read properties of undefined (reading 'get')

So how can i mock the interceptors? Could someone provide me with a example?

I have also tried this approach with the same results:

act(() => {
    jest.mock('axios', () => ({
      create: jest.fn(() => ({
        get: jest.fn(),
        interceptors: {
          request: { use: jest.fn(), eject: jest.fn() },
          response: { use: jest.fn(), eject: jest.fn() },
        },
      })),
    }));
    const mockedAxios = axios as jest.Mocked<typeof axios>;

    mockedAxios.get.mockResolvedValueOnce({ data: [{ user }] });
  });
Joel Suter
  • 83
  • 1
  • 2
  • 10
  • If I am not mistaken, `axios` is a Singleton, you should be able to do `import axios from 'axios';` and mock it in your tests like `axios.get = jest.fn()` – Max Larionov May 18 '22 at 08:28

1 Answers1

0

Axios is a singleton, meaning that you have a single instance wherever you import it.

It means that if we include it in our tests, it will be the same instance as in the code you are trying to test.

So if you'd import axios in your test code:

import axios from 'axios';

You would have a single axios instance in your component and tests. And you would be able to do anything with it, mocking and stubbing included. You could mock it with jest with:

jest.mock("axios");

I found a bit of more info on mocking axios with jest here.

Max Larionov
  • 420
  • 6
  • 19