Luis Osta
Luis Osta

Reputation: 144

Jest Mocked Function not calling mocked axios instance function (returns undefined)

I started by following the answer in this StackOverflow Question

But I added a helper function I use which creates a new Axios instance with the auth token associated with the user.

Which looks a little like this:

import axios from "axios";
const mockAxios: jest.Mocked<typeof axios> = jest.createMockFromModule("axios");

// this is the key to fix the axios.create() undefined error!
mockAxios.create = jest.fn(() => {
  return mockAxios;
});

export const createAuthenticatedInstance = () => {
  return mockAxios.create();
};
export default mockAxios;

Why does mockAxios.create() return undefined?

While the object 'mockAxios' (and the create function) is defined. When I actually call create it returns undefined despite the function being declared.

I know that I can side-step the issue by just returning mockAxios against but I'd like to understand why it doesn't work in the first place. What I'd expect is to return a new instance, which would be identical to mockAxios but it just returns undefined.

Upvotes: 1

Views: 1694

Answers (1)

Teneff
Teneff

Reputation: 32158

If you're creating an auto-mock (within __mocks__) it's meant to be a mock of the module and any helper functions are not expected to be within the module, but probably somewhere else with your code

Exmaple:

src/axios.utils.ts (utility module which exports axios and the function)
import axios from "axios";

export const createAuthenticatedInstance = (
  ...args: Parameters<typeof axios.create>
) => {
  return axios.create(...args);
};

export default axios;
src/__mocks__/axios.ts (the axios mock)
const axios: jest.Mocked<typeof import("axios").default> = jest.createMockFromModule(
  "axios"
);

axios.create.mockReturnThis();

export default axios;
src/api.ts (api implementation that uses the axios.util)

import axios from "axios";
import { createAuthenticatedInstance } from "./axios.utils";

const client = createAuthenticatedInstance({
  baseURL: "http://example.com:80/main",
});

export default {
  makeSomeReq: () => client.get<string>("/path"),
};
src/api.spec.ts (the test)

import api from "./api";
import axios, { AxiosResponse } from "axios";

jest.mock("axios");

const { get } = axios as jest.Mocked<typeof import("axios").default>;

describe("api", () => {
    it("should have created an axios instance", () => {
      expect(axios.create).toHaveBeenCalledWith({
        baseURL: "http://example.com:80/main",
      });
    });
})

working example

Upvotes: 2

Related Questions