1

I'm starting out with ReactJS and I want to Unit Test it. I made a simple Component which renders an HTML td element:

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

I wrote a 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');
});
...

But it fails with the following message:

...
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)
...

I'm not sure what it means, I'm guessing that it tries to put the td element into a div element but then how do people Unit Test a Component like I'm trying to Unit Test?

SBel
  • 3,315
  • 6
  • 29
  • 47

2 Answers2

0

You are right in guessing so. td must be a child of tr, which in turn must be a child of tbody or thead. The easy way out is to do something like this I guess

const datapointsTd = TestUtils.renderIntoDocument(
  <table>
    <tbody>
      <tr>
        <DatapointsTd type="currency" content="123" />
      </tr>
    </tbody>
  </table>
);
dannyjolie
  • 10,959
  • 3
  • 33
  • 28
  • I tried something like this and got a new error: "Invariant Violation: findAllInRenderedTree(...): instance must be a composite component" – randallreedjr Sep 02 '17 at 23:32
0

Initial Error

I ran into a similar problem trying to test a table header component using React.TestUtils:

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

where TableHeader was something like this

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

This led to the warning <th> cannot appear as a child of <div>.


Attempted Resolution

Attempting to use correct markup led to a new error.

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

The error here was Invariant Violation: findAllInRenderedTree(...): instance must be a composite component


Final Solution

Creating a wrapper component for the test worked for me.

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

See https://stackoverflow.com/a/40210219/1951290 for the answer that helped me.

randallreedjr
  • 340
  • 3
  • 7