简体   繁体   English

使用 jest.mock('axios') 时如何模拟拦截器?

[英]How to mock interceptors when using jest.mock('axios')?

When running a test using jest I have the basic test suit syntax:使用 jest 运行测试时,我有基本的测试服语法:

jest.mock('axios');

describe('app', () => {
    let render

    beforeEach(() => {
        axiosMock.get.mockResolvedValueOnce({
            data: {greeting: 'hello there'},
        }),
        render= renderApp()
    });

    test('should render something', () => {
        expect(something).toBeInTheDocument();
    });


});

The problem is I have interceptors in my code which when running the test with jest command outputs:问题是我的代码中有拦截器,当使用 jest 命令输出运行测试时:

TypeError: Cannot read property 'interceptors' of undefined类型错误:无法读取未定义的属性“拦截器”

and points to the interceptors object并指向拦截器对象

axiosInstance.interceptors.request.use(...

axiosInstance is the a variable storing the return of axios.create axiosInstance是存储axios.create返回值的axios.create

export const axiosInstance = axios.create({...

Refered to this axios thread on SO How do I test axios in jest but it doesn't involve any interceptors so didn't really help.在 SO How do I test axios in jest上参考了这个 axios 线程,但它不涉及任何拦截器,所以并没有真正的帮助。

This was enough in the end, plain and simple jest.fn()这最终就足够了,简单明了jest.fn()

jest.mock('axios', () => {
    return {
        interceptors: {
            request: { use: jest.fn(), eject: jest.fn() },
            response: { use: jest.fn(), eject: jest.fn() },
        },
    };
});

Make sure to mock out the interceptors and axios.create if used:如果使用,请确保模拟拦截器和axios.create

// Replace any instances with the mocked instance (a new mock could be used here instead):
axios.create.mockImplementation((config) => axios);

// Mock out the interceptor (assuming there is only one):
let requestCallback = () => {
  console.log("There were no interceptors");
};
axios.interceptors.request.use.mockImplementation((callback) => {
  requestCallback = callback;
});

// Mock out the get request so that it returns the mocked data but also calls the 
// interceptor code:
axios.get.mockImplementation(() => {
  requestCallback();
  return {
    data: "this is some data"
  };
});

Note if this doesn't work:请注意,如果这不起作用:

This example assumes that the create and interceptor calls are in a place where Jest can mock them out.此示例假定创建和拦截器调用位于 Jest 可以模拟它们的位置。 Placing the axios.create or axiosInstance.interceptors.request.use lines outside the scope of the function may cause the above mocking to fail.axios.createaxiosInstance.interceptors.request.use行放在函数范围之外可能会导致上述axiosInstance.interceptors.request.use失败。 This is an example file where Jest can mock them out:这是一个示例文件,Jest 可以在其中模拟它们:

const axios = require('axios');

const DEBUG = true;

const customRequest = (url) => {
  // Example of axios.create from https://www.npmjs.com/package/axios#axioscreateconfig
  const axiosInstance = axios.create({
    baseURL: 'https://some-domain.com/api/',
    timeout: 1000,
    headers: {'X-Custom-Header': 'foobar'}
  });

  // Example of interceptor taken from https://stackoverflow.com/a/52737325/7470360:
  axiosInstance.interceptors.request.use((config) => {
    if (DEBUG) { console.info("Request called", config); }
    return config;
  }, (error) => {
    if (DEBUG) { console.error("Request error ", error); }
    return Promise.reject(error);
  });

  return axiosInstance.get(url);
}

module.exports = customRequest;

The mocking code will mock out the axios.create call and the axiosInstance calls in customRequest .模拟代码将模拟出customRequestaxios.create调用和axiosInstance调用。 Moving either the creation or interception outside the function will cause the mocks to fail.将创建或拦截移动到函数之外将导致模拟失败。

Here is how I mocked axios.create and its interceptors :这是我嘲笑axios.create及其interceptors

jest.mock('axios', () => {
  return {
    create: () => {
      return {
        interceptors: {
          request: {eject: jest.fn(), use: jest.fn()},
          response: {eject: jest.fn(), use: jest.fn()},
        },
      };
    },
  };
});

Afterwards I was able to call the following in my test code:之后,我能够在我的测试代码中调用以下内容:

const client = axios.create({
  baseURL: 'http://some-url.com',
});

client.interceptors.request.use(config => {
  // some other test code
  return config;
});

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

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