【问题标题】:Testing functional components with renderIntoDocument使用 renderIntoDocument 测试功能组件
【发布时间】:2016-08-09 11:57:17
【问题描述】:

我正在学习使用 ReactTestUtils 库测试 React 无状态组件。这是我的简单组件:

import React from 'react';

const Greeter = ({name,place}) => (
  <h1>Hello,{name}. Welcome to the {place}.</h1>
);

export default Greeter;

这是我的测试规范,为了让 renderIntoDocument 正常工作,我按照 here 的建议将我的 Greeter 组件包装在一个 div 中:

import {expect} from 'chai';
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Greeter from '../Greeter';

describe('Greeter Components',() => {
  it('renders correctly',() => {
    var component = ReactTestUtils.renderIntoDocument(<div>
        <Greeter name="Vamsi" place="Hotel California"/>
    </div>);

    var hasH1 = ReactTestUtils.findRenderedDOMComponentWithTag(component,'h1');
expect(hasH1).to.be.ok;
  });
});

我得到了错误

findAllInRenderedTree(...):实例必须是复合组件。

我提供的代码是 jsbin here

【问题讨论】:

    标签: javascript unit-testing reactjs mocha.js karma-runner


    【解决方案1】:

    由于函数组件没有与之关联的实例,因此您不能直接将它们与 render 或 renderIntoDocument 一起使用。尝试包装函数组件是一个好主意,不幸的是,使用div 因类似原因不起作用。 DOM 组件也不返回组件实例,而是返回底层 DOM 节点。

    这就是说你不能使用测试工具函数原生组件作为你正在渲染的“根”组件。相反,您需要将函数组件包装在使用 createClass 或扩展 React.Component 的包装器组件中。

    class Wrapper extends React.Component {
      render() { 
        return this.props.children
      }
    }
    
    let component = renderIntoDocument(<Wrapper><Greeter /></wrapper>
    

    像这样的 Gotcha 可能有足够的理由使用第三方测试库,比如流行的酶,或者我自己的看法:teaspoon。两者都通过为您无缝包装和解包函数组件来抽象此类问题,因此您无需担心要渲染的组件类型。

    【讨论】:

    • 这对我帮助很大
    【解决方案2】:

    将功能组件包装在 &lt;div&gt; 中对我有用。你只需要搜索你想要测试的组件有点不同,即

    const props = { p1: "1" }
    test('Foo renders correctly classed div', () => {
      const cpt = TestUtils.renderIntoDocument(<div><Foo {...props} /></div>);
      const myNode = ReactDOM.findDOMNode(cpt.childNodes[0]);
      expect(myNode.className).toBe('my-class');
    });
    

    请注意,您可以使用cpt.childNodes[0] 定位myNode 进行测试

    【讨论】:

      【解决方案3】:

      为了改进@monastic-panic的回答,我的两分钱:

      您不必为此创建一个类。动态执行:

      import createReactClass from 'create-react-class';
      
      // need to be a class component
      const Clazz = createReactClass({
        render: () => {
          return <YourFunctionalComponentName {...props} />;
        },
      });
      
      ReactTestUtils.renderIntoDocument(<Clazz />);
      

      【讨论】:

        猜你喜欢
        • 2020-12-18
        • 2021-09-04
        • 2019-07-09
        • 2021-04-25
        • 1970-01-01
        • 2019-07-22
        • 2021-08-18
        • 2020-07-17
        • 2019-12-10
        相关资源
        最近更新 更多