【问题标题】:Mocking external class method inside React component with jest用玩笑模拟 React 组件内的外部类方法
【发布时间】:2018-01-26 21:53:57
【问题描述】:

我正在尝试测试组件方法,该方法在内部执行对外部资源的网络调用。阅读文档后,我仍然不知道该怎么做。任何人都可以帮忙吗?这是我的代码(为简洁起见隐藏了一些部分):

我的组件:

import React from 'react'
import ResourceService from '../../modules/resource-service'

export default class SliderComponent extends React.Component {
  setActiveSlide = (activeSlide) => {
    ResourceService.getData({
      id: activeSlide,
    }).then((data) => {
      if (data) {
        this.setState({
          data,
        })
      }
    })
  }
}

资源服务:

import axios from 'axios'

export default class ResourceService {
  static getData(params) {
    return axios.post('/api/get_my_data', params)
      .then((resp) => resp.data)
  }
}

期望的测试(据我了解):

import React from 'react'
import { mount, configure } from 'enzyme'
import SliderComponent from '../../../app/components/slider'

test('SliderComponent changes active slide when setActiveSlide is  
called', () => {
  const wrapper = mount(
    <SliderComponent />
  );
  wrapper.instance().setActiveSlide(1);
  // some state checks here
});

我需要在SliderComponent 内模拟ResourceService.getData 调用,我真的不明白怎么做...

【问题讨论】:

    标签: reactjs mocking jestjs


    【解决方案1】:

    您可以在测试中导入您的ResourceService,并使用jest.fn(() =&gt; ...) 模拟getData 方法。这是一个例子:

    import React from 'react'
    import { mount, configure } from 'enzyme'
    import ResourceService from '../../../modules/resource-service'
    import SliderComponent from '../../../app/components/slider'
    
    test('SliderComponent changes active slide when setActiveSlide is  
    called', () => {
       // you can set up the return value, you can also resolve/reject the promise 
       // to test different scnarios
       ResourceService.getData = jest.fn(() => (
          new Promise((resolve, reject) => { resolve({ data: "testData" }); }));
    
      const wrapper = mount(<SliderComponent />);
    
      wrapper.instance().setActiveSlide(1);
    
      // you can for example check if you service has been called
      expect(ResourceService.getData).toHaveBeenCalled();
      // some state checks here
    });
    

    【讨论】:

    • 非常感谢,这正是我所需要的。 A 没有尝试这种方法,而是尝试在 mocks 文件夹中创建模拟 ResouceService 类...
    • 没有问题,乐于助人:)
    【解决方案2】:

    尝试使用 axios-mock-adapter 在您的测试中模拟 postreq。

    它应该看起来像这样(可能需要更多调整):

    import React from 'react'
    import { mount, configure } from 'enzyme'
    import SliderComponent from '../../../app/components/slider'
    import axios from'axios';
    import MockAdapter = from'axios-mock-adapter';
    
    test('SliderComponent changes active slide when setActiveSlide is  
    called', () => {
    let mock = new MockAdapter(axios)
    //you can define the response you like
    //but your params need to be accordingly to when the post req gets called
     mock.onPost('/api/get_my_data', params).reply(200, response) 
    
      const wrapper = mount(
        <SliderComponent />
      );
      wrapper.instance().setActiveSlide(1);
      // some state checks here
    });
    

    请务必查看 axios-mock-adapter 的文档

    【讨论】:

    • 感谢您的回答,但我不希望尽可能使用其他模块。上面由 margaretkru 提出的原生 Jest 解决方案完全符合我的需求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 2021-10-14
    • 2020-09-23
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多