簡體   English   中英

如何用笑話測試 axios 攔截器

[英]how to test axios interceptors with jest

在我的項目中,我有一個命名空間,它導出一些使用 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);
    }
);

我想測試這個攔截器是否按預期工作,我在這里搜索 forms 並搜索了很多但所有答案基本上都是 mocking 攔截器沒有測試它。

我努力了:

  1. mocking axios 發布請求的響應並檢查返回的 AxiosPromise 但它只包含我嘲笑的結果。 當我使用mockResolvedValue進行模擬時,它似乎忽略了攔截器。
  2. 我嘗試向模擬的 axios 實例添加一個攔截器,但這也不起作用。

謝謝

將 function 拉出並在沒有 axios 的情況下對其進行測試怎么樣?

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

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

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

現在您可以測試對 axios 依賴較少的函數 onFullfilled 和 onRejected。

您必須模擬攔截器並運行回調。

這是有關如何執行此操作的示例:

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();
});

使用這個模擬功能

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM