使用renderIntoDocument测试功能组件

时间:2016-04-17 21:06:52

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

我正在学习使用 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

3 个答案:

答案 0 :(得分:13)

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

可以说,您不能将test utils函数本机组件用作&#34; root&#34;您正在渲染的组件。相反,您需要将函数组件包装在使用createClass或扩展React.Component的包装器组件中。

class Wrapper extends React.Component {
  render() { 
    return this.props.children
  }
}

let component = renderIntoDocument(<Wrapper><Greeter /></wrapper>
像这样可能有足够的理由使用第三方测试库,如流行的酶,或我自己的看法:teaspoon。通过无缝地包装和展开功能组件,这两个问题都可以解决这个问题,因此您不必担心要尝试渲染的组件类型。

答案 1 :(得分:0)

<div>中包装功能组件对我有用。您只需要以不同的方式搜索要测试的组件,即

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');
});

请注意,您可以使用myNode

定位cpt.childNodes[0]进行测试

答案 2 :(得分:0)

为了改善@ monastic-panic的答案,我的两分钱:

你不必为此创建一个类。动态地做:

import createReactClass from 'create-react-class';

// need to be a class component
const Clazz = createReactClass({
  render: () => {
    return <YourFunctionalComponentName {...props} />;
  },
});

ReactTestUtils.renderIntoDocument(<Clazz />);