用笑话测试axios拦截器

时间:2020-05-12 19:17:31

标签: testing mocking jestjs axios interceptor

我正在使用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函数在拦截器中由于某种原因没有被嘲笑。 测试失败。

1 个答案:

答案 0 :(得分: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获得类似的结果(然后不需要jest.mock,但是必须导入getAccessToken函数而无需进行结构分解)。