单元测试ReactJS组件产生不变违规:findComponentRoot

时间:2016-03-19 12:43:19

标签: javascript unit-testing reactjs jestjs

我开始使用ReactJS,我想进行单元测试。我创建了一个简单的Component,它呈现了一个HTML td元素:

...
render() {
    return (
        <td>{this.props.type == 'currency' ? '$' : ''}{this.props.content}</td>
    );
}
...

我写了一个Jest Unit Test:

...
it('currency should prepend dollar sign', () => {
    const datapointsTd = TestUtils.renderIntoDocument(
        <DatapointsTd type="currency" content="123" />
    );

    const datapointsTdNode = ReactDOM.findDOMNode(datapointsTd);

    expect(datapointsTdNode.textContent).toEqual('$123');
});
...

但它失败并显示以下消息:

...
Warning: validateDOMNesting(...): <td> cannot appear as a child of <div>. See di
v > DatapointsTd > td.
 FAIL  __tests__\DatapointsTd-test.js (49.753s)
- DatapointsTd › it should display content in a td
  - Invariant Violation: findComponentRoot(..., .0): Unable to find element. Thi
s probably means the DOM was unexpectedly mutated (e.g., by the browser), usuall
y due to forgetting a <tbody> when using tables, nesting tags like <form>, <p>,
or <a>, or using non-SVG elements in an <svg> parent. Try inspecting the child n
odes of the element with React ID ``.
        at invariant (node_modules\react\node_modules\fbjs\lib\invariant.js:39:1
5)
...

我不确定这意味着什么,我猜它试图将td元素放入div元素但是人们如何单元测试组件就像我试图进行单元测试?

2 个答案:

答案 0 :(得分:0)

你猜对了。 td必须是tr的孩子,而tr必须是tbody或thead的孩子。最简单的方法就是做这样的事情我猜

const datapointsTd = TestUtils.renderIntoDocument(
  <table>
    <tbody>
      <tr>
        <DatapointsTd type="currency" content="123" />
      </tr>
    </tbody>
  </table>
);

答案 1 :(得分:0)

初始错误

我遇到了类似的问题,尝试使用React.TestUtils测试表头组件:

var header = TestUtils.renderIntoDocument(
  <TableHeader text='Test' />
);

其中TableHeader是这样的

class TableHeader extends React.Component {
  render() {
    return(<th>{this.props.text}</th>);
  }
}

这导致警告<th> cannot appear as a child of <div>

尝试解决

尝试使用正确的标记会导致新的错误。

var header = TestUtils.renderIntoDocument(
  <table>
    <thead>
      <tr>
        <TableHeader text='Test' />
      </tr>
    </thead>
  </table>
);

此处的错误是Invariant Violation: findAllInRenderedTree(...): instance must be a composite component

最终解决方案

为我测试创建一个包装器组件。

class TestHeader extends React.Component {
  render() {
    return (
      <table>
        <thead>
          <tr>
            <TableHeader text={this.props.text} />
          </tr>
        </thead>
      </table>
    )
  }
}

var header = TestUtils.renderIntoDocument(
  <TestHeader text='Test' />
);

有关帮助我的答案,请参阅https://stackoverflow.com/a/40210219/1951290