【问题标题】:Unit test interceptor logic in AxiosAxios 中的单元测试拦截器逻辑
【发布时间】: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);
});

【问题讨论】:

    标签: javascript axios jestjs


    【解决方案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)
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-04
      • 2019-06-29
      • 2019-04-28
      • 2019-09-12
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      相关资源
      最近更新 更多