如何用jest测试axios拦截器

iaqfqrcu  于 2023-09-28  发布在  Jest
关注(0)|答案(4)|浏览(191)

在我的项目中,我有一个命名空间,它导出了一些使用Axios的函数,在同一个文件中,我向Axios示例添加了一个拦截器,如下所示:

axios.interceptors.response.use(
    (res) => res,
    (error) => {
      if (
        error.response &&
        (error.response.status?.toString() === "400" ||
          error.response.status?.toString() === "403" ||
          error.response.status?.toString() === "404")
      ) {
        return Promise.reject(
          Error(JSON.stringify(error.response.data?.status?.errors[0]))
        );
      } else if (error.response) {
        return Promise.reject(
          Error(
            `server responsed with the following code: ${error.response?.status} and the following message: ${error.response?.statusText}`
          )
        );
      } else if (error.request) {
        return Promise.reject(
          Error(
            "The request was made but no response was received, check your network connection"
          )
        );
      } else Promise.reject(error);
    }
);

我想测试一下这个拦截器是否能按预期工作,我在这里搜索了很多表格并在谷歌上搜索了很多,但所有的答案基本上都是嘲笑拦截器而不是测试它。
我试过:
1.模拟axios post请求的响应,并检查返回的AxiosPromise,但它只包含我模拟的结果。当我使用mockResolvedValue进行模拟时,它似乎忽略了拦截器。
1.我试过在模拟的axios示例中添加一个拦截器,但也没有成功。
谢谢

jk9hmnmh

jk9hmnmh1#

把函数取出并在没有axios的情况下测试它怎么样?

import axios, { AxiosError, AxiosResponse } from 'axios'

export const onFulfilled = (response: AxiosResponse) => {
  // Your interceptor handling a successful response
}
export const onRejected = (error: AxiosError) => {
  // Your interceptor handling a failed response
}

axios.interceptors.response.use(onFulfilled, onRejected)

现在,您可以测试onFullfilled和onRejected函数,对axios的依赖性更少。

3duebb1j

3duebb1j2#

您必须模拟拦截器并运行回调。
下面是一个关于如何做到这一点的例子:
httpService.ts

import axios from "axios";
import { toast } from "react-toastify";

axios.interceptors.request.use((config) => {
  config.baseURL = process.env.API_URL || "http://localhost:5000";
  return config;
});

axios.interceptors.response.use(null, (error) => {
  const expectedError =
    error.response &&
    error.response.status >= 400 &&
    error.response.status < 500;

  if (!expectedError) {
    toast.error("An unexpected error occured");
  }

  return Promise.reject(error);
});

export default {
  get: axios.get,
  post: axios.post,
  put: axios.put,
  delete: axios.delete,
};

httpService.test.ts

import axios from "axios";
import { toast } from "react-toastify";
import "./httpService";

jest.mock("axios", () => ({
  __esModule: true,
  default: {
    interceptors: {
      request: { use: jest.fn(() => {}) },
      response: { use: jest.fn(() => {}) },
    },
  },
}));

const fakeError = {
  response: {
    status: undefined,
  },
};

const mockRequestCallback = (axios.interceptors.request.use as jest.Mock).mock
  .calls[0][0];
const mockResponseErrorCallback = (axios.interceptors.response.use as jest.Mock)
  .mock.calls[0][1];
const toastErrorSpy = jest.spyOn(toast, "error");

beforeEach(() => {
  toastErrorSpy.mockClear();
});

test("request error interceptor", () => {
  expect(mockRequestCallback({})).toStrictEqual({
    baseURL: "http://localhost:5000",
  });
});

test("unexpected error on response interceptor", () => {
  fakeError.response.status = 500;

  mockResponseErrorCallback(fakeError).catch(() => {});
  expect(toastErrorSpy).toHaveBeenCalled();
});

test("expected error on response interceptor", () => {
  fakeError.response.status = 400;

  mockResponseErrorCallback(fakeError).catch(() => {});
  expect(toastErrorSpy).not.toHaveBeenCalled();
});
balp4ylt

balp4ylt3#

我也有同样的问题,我是这样解决的:

const axiosResponse = await axios.get(your-url);

  expect(axiosResponse.config.headers.Authorization).toBe('Bearer test-token');

通过axiosResponse,您可以测试在拦截器中设置的所有逻辑

f2uvfpb9

f2uvfpb94#

使用此模拟功能

jest.mock('axios', () => {
   return {
      interceptors: {
         request: {
            use: jest.fn(),
            eject: jest.fn()
         },
         response: {
            use: jest.fn(),
            eject: jest.fn()
         },
      },
   };
});

相关问题