用玩笑测试axios拦截器

问题描述 投票:0回答:1

我正在使用axios拦截器向其标头添加授权令牌。拦截器工作正常。

//api.js
import { getAccessToken } from "./utils";

const apiInstance = axios.create();

apiInstance.interceptors.request.use((configIns) => {

  const token = getAccessToken();
  configIns.headers.Authorization = token ? `Bearer ${token}` : "";
  return configIns;

});

export { apiInstance };

这是我的测试文件,用于测试拦截器。

// api.test.js

import { apiInstance } from "./api"
import {getAccessToken} from "./utils";

describe("request interceptor", () => {
    it("API request should add authorization token to header", () => {

      const getAccessToken = jest.fn(getAccessToken);
      getAccessTokenMock.mockReturnValue("token");

      const result = apiInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });

      expect(getAccessTokenMock.mock.calls.length).toBe(1);
      expect(result.headers).toHaveProperty("Authorization");
    });
  });

但是getAccessToken函数在拦截器中由于某种原因没有被嘲笑。测试失败。

testing mocking jestjs axios interceptor
1个回答
1
投票

这不是玩笑中嘲笑的方式。通过调用(我假设变量应该是getAccessTokenMock,而不是getAccessToken):

const getAccessTokenMock = jest.fn(getAccessToken);
getAccessTokenMock.mockReturnValue("token");

[您要做的是:创建一个新的本地模拟,当该模拟被调用时,将调用您的getAccessToken函数。然后,您模拟返回值。但是,永远不会调用getAccessTokenMock,因为它与实现中的实例不同!

您需要做的是从getAccessToken文件中模拟实际功能./utils。例如,可以这样做:

import { apiInstance } from "./api"
import {getAccessToken} from "./utils";

// Mock here:
jest.mock('./utils', () => ({
  getAccessToken: jest.fn(() => 'token')
});

describe("request interceptor", () => {
  it("API request should add authorization token to header", () => {
    const result = apiInstance.interceptors.request.handlers[0].fulfilled({ headers: {} });

    expect(getAccessToken.mock.calls.length).toBe(1);
    expect(result.headers).toHaveProperty("Authorization");
  });
});

这里发生的事情是,在加载文件时,jest.mock将首先运行,并用模拟替换您的getAccessToken实现-然后可以从实现和测试(相同的实例)中访问它,这意味着您可以验证它是否已被调用。

请参阅有关模拟herehere的更多信息。另外,您也可以使用spyOn获得相似的结果(然后不需要spyOn,但是必须导入jest.mock函数而无需进行结构分解)。

© www.soinside.com 2019 - 2024. All rights reserved.