简体   繁体   English

Axios 中的单元测试拦截器逻辑

[英]Unit test interceptor logic in Axios

I have an interceptor set up in Axios that will refresh tokens and then retry the call if the initial HTTP response is a 401.我在 Axios 中设置了一个拦截器,它会刷新令牌,然后在初始 HTTP 响应是 401 时重试调用。

I'm trying to unit test this logic by mocking Axios request to return a 401 and then a valid response (see a simplified version below) and asserting that it gets called twice.我试图通过模拟 Axios 请求返回 401 和有效响应(参见下面的简化版本)并断言它被调用两次来对这个逻辑进行单元测试。

My problem is that because I'm mocking request the interceptor doesn't seem to run.我的问题是,因为我在嘲笑请求,拦截器似乎没有运行。 Rather than retry the request, I get the stubAuthError returned.我没有重试请求, stubAuthError返回了stubAuthError

Is there any way of achieving what I'm after, or is there a better way to test this?有什么方法可以实现我所追求的目标,还是有更好的方法来测试它?

index.js索引.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 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);
});

interceptors are registered sequentially, similar to express middleware,拦截器是按顺序注册的,类似于express中间件,

you can access axios.interceptors.request and axios.interceptors.response to unit test functions registered on the interceptor manager您可以访问axios.interceptors.requestaxios.interceptors.response到拦截器管理器上注册的单元测试函数

for example:例如:

on my main.js :在我的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
};

on my main.test.js :在我的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)
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM