用玩笑测试 axios 拦截器
Testing axios interceptors with jest
我正在使用 axios 拦截器将授权令牌添加到其 header。拦截器工作正常。
//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
函数在拦截器中由于某种原因没有被模拟。
测试失败。
Jest 中的模拟不是这样工作的。通过调用(我假设变量应该是 getAccessTokenMock
,而不是 getAccessToken
):
const getAccessTokenMock = jest.fn(getAccessToken);
getAccessTokenMock.mockReturnValue("token");
你所做的是:你创建新的本地模拟,当被调用时,会调用你的 getAccessToken
函数。然后你模拟 return 值。但是,您的 getAccessTokenMock
永远不会被调用,因为它与您的实现中的实例不同!
您需要做的是从 ./utils
文件中模拟您的实际函数 getAccessToken
。可以这样做,例如,像这样:
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
的实现替换为模拟 - 然后可以从两者访问它实现和测试(作为同一个实例),意味着你可以验证它是否被调用。
请找到更多关于 mocks here or here. Alternatively you can also use spyOn
的信息以获得类似的结果(那么你不需要 jest.mock
,但你必须导入你的 getAccessToken
函数而不解构)。
我正在使用 axios 拦截器将授权令牌添加到其 header。拦截器工作正常。
//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
函数在拦截器中由于某种原因没有被模拟。
测试失败。
Jest 中的模拟不是这样工作的。通过调用(我假设变量应该是 getAccessTokenMock
,而不是 getAccessToken
):
const getAccessTokenMock = jest.fn(getAccessToken);
getAccessTokenMock.mockReturnValue("token");
你所做的是:你创建新的本地模拟,当被调用时,会调用你的 getAccessToken
函数。然后你模拟 return 值。但是,您的 getAccessTokenMock
永远不会被调用,因为它与您的实现中的实例不同!
您需要做的是从 ./utils
文件中模拟您的实际函数 getAccessToken
。可以这样做,例如,像这样:
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
的实现替换为模拟 - 然后可以从两者访问它实现和测试(作为同一个实例),意味着你可以验证它是否被调用。
请找到更多关于 mocks here or here. Alternatively you can also use spyOn
的信息以获得类似的结果(那么你不需要 jest.mock
,但你必须导入你的 getAccessToken
函数而不解构)。