网站搜索

javascript - 使用 jest 测试 axios.create() 实例


我尝试了这个任务中的许多解决方案。我想在不使用任何库(jest-axios-mock、moaxios、msw 等)的情况下测试 axios 实例的 API 调用。我希望这是可能的,因为我成功测试了简单的 axios 调用(axios.get/axios.post,没有使用 .create)。主要问题是,当我尝试测试 axios 实例调用时,在不同尝试中遇到了三个主要错误。

1 axios_instance_1.axiosInstance 不是一个函数

2 无法读取未定义的属性 'then'

3 无法读取未定义的属性 'post'

当我尝试绕过模块模拟(jestjs.io/docs/bypassing-module-mocks)时,我会遇到这个问题

我上一次的尝试看起来像这样

axios-instance.ts

import axios from "axios";
export const axiosInstance = axios.create({
    headers: {'X-Custom-Header': 'foobar'}
})

api.ts

import { axiosInstance } from "../instancec/axios-instance";
export const axiosInstanceCounter = () => {
  return axiosInstance({
    method: 'post'
  }).then((data) => {
    console.log(data)
  })
}

axios.test.ts

import { axiosInstanceCounter } from '../features/api/axiosTest';
import { axiosInstance } from '../features/instancec/axios-instance';
import axios, { AxiosResponse } from 'axios';

jest.mock('../features/instancec/axios-instance', () => ({
   const instance = {
     create: jest.fn(),
   };
   return jest.fn(() => instance);
}));

it('Axios instance standart test', async () => {
    (axiosInstance.post as jest.Mock).mockResolvedValueOnce(() =>
      Promise.resolve(),
    );
    await axiosInstanceCounter();
    expect(axiosInstance).toBeCalledTimes(1);
});

我收到的最后一个错误是Cannot read 'post' of undefined。在mocks文件夹中创建mocks文件并从那里导出也没有帮助。我不太明白为什么会发生这种情况,并且对任何提示都将不胜感激,我也尝试过使用jest.spyOn,但这也失败了。

对解决方案的补充

我用 ts-jest 替换 mocked() 以避免警告

const mockedAxiosInstance = axiosInstance as jest.MockedFunction<
  typeof axiosInstance
>;

答案#1

这也可以,而且对于你的目的更简单

import { axiosInstanceCounter } from "../features/api/axiosTest";
import { axiosInstance } from "../features/instancec/axios-instance";

let apiSpy;
describe("getPokemonOptions", () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });
  it("Axios instance standart test", async () => {
    apiSpy = jest.spyOn(axiosInstance, "post");
    apiSpy.mockResolvedValue({});
    await axiosInstanceCounter();
    expect(axiosInstance).toBeCalledTimes(1);
  });
});

答案#2

正如你所看到的,return axiosInstance({ 意味着 axiosInstance 是一个函数,那么如果你想测试 axiosInstanceCounter 函数,只需将 axiosInstance 模拟为一个普通函数(在你的情况下 API 调用不会返回任何内容):

api.test.ts/测试 api.ts

import { AxiosPromise } from "axios";
import { mocked } from "ts-jest/utils"; // a helper function from ts-jest
import { axiosInstanceCounter } from '../features/api/axiosTest'; // should be ../features/api ???
import { axiosInstance } from '../features/instancec/axios-instance';

jest.mock("../features/instancec/axios-instance");

describe("api", () => {
  describe("axiosInstanceCounter()", () => {
    it("should call api with correct parameters", async () => {
      // mock to resolve a Promise<void>
      mocked(axiosInstance).mockResolvedValue(Promise.resolve() as unknown as AxiosPromise<void>);

      await axiosInstanceCounter();

      expect(axiosInstance).toHaveBeenCalledWith({ method: "post" });
    });
  });
});