Jest mock axios does not work if the class is initialised in the setupTests

Viewed 22

I'm trying to test my backend class which uses axios to get some data from the backend. I've mocked axios and stubbed the get function to return some values. This works great!
However if I create a new instance of the Backend in the setupTests the test fails. If I remove the beforeEach from the setupTests and add it to the test file, the test succeeds again.
The test fails because the stub has not been called.
I'm using the setupTests to mock the dependencies for other tests. Whilst mocking this, I create a subclass instance of the Backend.

Test:

import {Backend} from "../../../shared/utils/backend";
import axios from "axios";

jest.mock("axios");

describe("backend", () => {
   test("When getList is called data is returned", async () => {
    (axios.get as jest.Mock) = jest.fn().mockResolvedValue(Promise.resolve({
      data: [{
        prop: "test",
        otherProp: 2
      }]
    }));

    const backend = new Backend("baseUrl");
    const data = await backend.getList("testUrl");
    expect(axios.get).toHaveBeenCalledWith("baseUrl/testUrl");
    expect(data).toHaveLength(1);
  });
});

SetupTests

import "@testing-library/jest-dom";
import {Backend} from "./shared/utils/backend";

new Backend("test");

Backend class

import axios from "axios";

export class Backend {
  private _baseUrl: string;

  constructor(baseUrl: string) {
    axios.defaults.headers.get["Access-Control-Allow-Origin"] = "*";
    axios.defaults.headers.get["Access-Control-Allow-Credentials"] = "true";
    this._baseUrl = baseUrl;
  }
  async getList(url: string): Promise<any[] | undefined> {
    const data = await axios.get<any[]>(`${this._baseUrl}/${url}`);
    if (data) {
      return data.data;
    }
    return undefined;
  }
}
1 Answers

In the end I managed to circumvent the problem. My dependencies wanted a Backend in the constructor. My BackendMock was an extension of the Backend class. This resulted in implicitly creating a Backend whenever I created the mock.
I created an interface for the Backend and changed the dependencies to use the interface instead of the class. Now the Backend is no longer created and the tests now work.

Related