【问题标题】:How to test properties and functions on a React component?如何测试 React 组件的属性和功能?
【发布时间】:2016-06-14 17:05:59
【问题描述】:

我已经用enzyme 尝试了所有方法,但是,我在下面找不到测试这些属性的正确方法。请记住,这个组件被包裹在一个虚拟的 Provider 组件中,以便我可以传递必要的道具(即Store)以进行安装。

1) 挂载后,在实例上设置一个属性(例如this.property

2) 添加了一个事件监听器

3) 在事件监听器上,someFunction 被调用

class SampleComponent extends Component {

  componentDidMount() {
    this.property = 'property';
    window.addEventListener('scroll', this.someFunction, true);
  }

  someFunction = () => {
    return 'hello';
  };

  render() {
    return <h1>Sample</h1>; 
  }
}

export default EvalueeExposureList;

【问题讨论】:

    标签: reactjs mocha.js enzyme


    【解决方案1】:

    好的,我已经根据与 OP 的讨论更新了我的答案。被测组件有一个 redux 提供者和连接的组件作为子组件,因此我们选择使用酶浅 API。


    关于跟踪和测试addEventListener,您可以使用sinon 库来创建一个间谍,它会暂时“替换”window.addEventListener。这使您可以访问调用计数以及调用它的参数。

    使用酶和摩卡咖啡,我创建了以下测试,这些测试都通过了。前两个测试涵盖了上述所有案例,为了更好地衡量,我添加了另一个关于如何测试someFunction 的输出。

    import React from 'react';
    import { expect } from 'chai';
    import sinon from 'sinon';
    import { shallow } from 'enzyme';
    
    // Under test.
    import SampleComponent from './SampleComponent';
    
    describe('SampleComponent', () => {
      let addEventListenerSpy;
    
      beforeEach(() => {
        // This replaces the window.addEventListener with our spy.
        addEventListenerSpy = sinon.spy(window, 'addEventListener');
      });
    
      afterEach(() => {
        // Restore the original function.
        window.addEventListener.restore();
      });
    
      // This asserts your No 1.
      it(`should set the property`, () => {
        const wrapper = shallow(<SampleComponent />);
        wrapper.instance().componentDidMount(); // call it manually
        expect(wrapper.instance().property).equal('property');
      });
    
      // This asserts your No 2 and No 3.  We know that by having
      // passed the someFunction as an argument to the event listener
      // we can trust that it is called.  There is no need for us
      // to test the addEventListener API itself.
      it(`should add a "scroll" event listener`, () => {
        const wrapper = shallow(<SampleComponent />);
        wrapper.instance().componentDidMount(); // call it manually
        expect(addEventListenerSpy.callCount).equal(1);
        expect(addEventListenerSpy.args[0][0]).equal('scroll');
        expect(addEventListenerSpy.args[0][1]).equal(wrapper.instance().someFunction);
        expect(addEventListenerSpy.args[0][2]).true;
      });
    
      it(`should return the expected output for the someFunction`, () => {
        const wrapper = mount(<SampleComponent />);
        expect(wrapper.instance().someFunction()).equal('hello');
      });
    });
    

    值得注意的是,我在节点上运行我的测试,但我的mocha 配置中有一个jsdom 设置,这可能是负责创建window.addEventListener 以在我的测试环境中使用的候选人.您是通过浏览器还是节点运行测试?如果节点你可能需要做一些类似于我的事情。

    【讨论】:

    • 非常感谢您的详细回答。但是,我继续为类属性获取undefined。如上所示,我有一些坐在构造函数内部,一些设置在componentDidMount,但没有一个返回任何值:console.log(wrapper.instance().someProperty)
    • 您是否有机会通过示例测试更新您的问题?
    • 我明白了,我的组件位于模拟提供程序中,因此 instance 方法返回父级而不是所需的实例。这很不幸,因为我无法使用instance 方法获取child 组件的实例。
    • 你应该导出你的包装组件和没有包装的组件,以便你可以单独测试它。
    • 你不需要一个有商店的Provider来传递props,你可以简单地通过测试传递props。例如mount(&lt;MyComponent propOne="foo" /&gt;)
    猜你喜欢
    • 2021-09-04
    • 2021-08-18
    • 2021-08-30
    • 1970-01-01
    • 2020-01-02
    • 2021-04-25
    • 2020-04-08
    • 2021-04-13
    • 2019-08-06
    相关资源
    最近更新 更多