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

Posted

技术标签:

【中文标题】使用 jest.mock(\'axios\') 时如何模拟拦截器?【英文标题】:How to mock interceptors when using jest.mock('axios')?使用 jest.mock('axios') 时如何模拟拦截器? 【发布时间】:2020-06-10 03:18:56 【问题描述】:

使用 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();
    );


);

问题是我的代码中有拦截器,当使用 jest 命令输出运行测试时:

TypeError:无法读取未定义的属性“拦截器”

并指向拦截器对象

axiosInstance.interceptors.request.use(...

axiosInstance是存储axios.create返回的变量

export const axiosInstance = axios.create(...

在 SO How do I test axios in jest 上引用了这个 axios 线程,但它不涉及任何拦截器,所以并没有真正的帮助。

【问题讨论】:

【参考方案1】:

到此为止,简单明了jest.fn()

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

【讨论】:

我没有使用 axios.create 创建 axios 实例,如何模拟拦截器?在我的单元测试中,axios 像这样被嘲笑 jest.mock('axios'); const mockedAxios = axios as jest.Mocked;【参考方案2】:

确保模拟出拦截器和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"
  ;
);

注意如果这不起作用:

此示例假定创建和拦截器调用位于 Jest 可以模拟它们的位置。将axios.createaxiosInstance.interceptors.request.use 行放在函数范围之外可能会导致上述模拟失败。这是 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://***.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;

模拟代码将模拟出axios.create 调用和customRequest 中的axiosInstance 调用。将创建或拦截移到函数外都会导致模拟失败。

【讨论】:

Tnx 的帮助但是我已经能够用通常的 jest.mock('axios',callback) 来模拟它无论如何我遇到了另一个问题,所以如果你可以看看它***.com/questions/60428640/…昨天赞成这个答案【参考方案3】:

这是我嘲笑axios.create 及其interceptors 的方式:

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

之后我可以在我的测试代码中调用以下代码:

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

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

【讨论】:

唯一对我有用的例子

以上是关于使用 jest.mock('axios') 时如何模拟拦截器?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Jest 测试身份验证标头?

用 Jest 抛出的异步测试

如何使用 jest.mock 模拟 useRef 和反应测试库

运行测试时出错 - jest.mock 不是函数

Jest.fn-使用jest.mock时返回的值返回未定义

jest.mock():如何使用工厂参数模拟 ES6 类默认导入