Axios 中的单元测试拦截器逻辑
Posted
技术标签:
【中文标题】Axios 中的单元测试拦截器逻辑【英文标题】:Unit test interceptor logic in Axios 【发布时间】:2019-05-30 04:04:12 【问题描述】:我在 Axios 中设置了一个拦截器,如果初始 HTTP 响应是 401,它将刷新令牌,然后重试调用。
我正在尝试通过模拟 Axios 请求以返回 401,然后返回有效响应(请参阅下面的简化版本)并断言它被调用两次来对该逻辑进行单元测试。
我的问题是因为我在模拟请求,所以拦截器似乎没有运行。我没有重试请求,而是返回了stubAuthError
。
有什么方法可以实现我所追求的,或者有更好的方法来测试它吗?
index.js
const axios = require('axios');
axios.interceptors.response.use(
response => response,
error =>
const status = error.response ? error.response.status : null;
if (status === 401)
return makeRequest();
else
return Promise.reject(error);
);
async function makeRequest()
return axios.request('url');
module.exports =
makeRequest
;
index.spec.js
const axios = require('axios');
const makeRequest = require('./index');
const stubAuthError = response: status: 401 ;
const stubResponse = data: foo: 'bar' ;
it('should make the request twice', async () =>
expect.assertions(1);
axios.request = jest.fn();
axios.request
.mockRejectedValueOnce(stubAuthError)
.mockResolvedValueOnce(stubResponse);
try
await makeRequest();
catch (error)
expect(axios.request).toHaveBeenCalledTimes(2);
);
【问题讨论】:
【参考方案1】:拦截器是按顺序注册的,类似于express中间件,
您可以访问axios.interceptors.request
和axios.interceptors.response
以访问在拦截器管理器上注册的单元测试功能
例如:
在我的main.js
:
let axios = require('axios');
axios.interceptors.response.use(
response => response,
error =>
const status = error.response ? error.response.status : null;
if (status === 401)
return makeRequest();
else
return Promise.reject(error);
);
async function makeRequest()
return axios.request('https://randomuser.me/api/');
module.exports =
makeRequest
;
在我的main.test.js
:
let axios = require('axios');
//
// based on your question, we don't want to test "makeRequest"
// so, I'm loading the file only to register the interceptors
//
require('./main');
let stubAuthError = response: status: 401 ;
let stubExceptionError = response: status: 500 ;
let stubResponse = data: foo: 'bar' ;
test("interceptor fulfilled", () =>
let res = axios.interceptors.response.handlers[0].fulfilled(stubResponse);
expect(res).toEqual(stubResponse);
);
test("interceptor rejected => makeRequest", () =>
let originalAxiosRequest = axios.request;
// this fn will be called by "makeRequest"
axios.request = jest.fn();
axios.interceptors.response.handlers[0].rejected(stubAuthError);
expect(axios.request).toHaveBeenCalledTimes(1);
axios.request = originalAxiosRequest;
);
test("interceptor rejected => exception", async () =>
await expect(axios.interceptors.response.handlers[0].rejected(stubExceptionError)).rejects.toEqual(stubExceptionError)
);
【讨论】:
以上是关于Axios 中的单元测试拦截器逻辑的主要内容,如果未能解决你的问题,请参考以下文章
如何对使用 Axios(或其他异步更新)的 Vue 组件进行单元测试?