Search code examples
reactjsreactjs-testutils

React Test : Finding Component within Component


I can find a component at the first 'finder' in the code below

var myComponent = ReactTestUtils.findRenderedDOMComponentWithClass(myDiv, 'myComponent')

If I then use the returned Component object and use that to find an even deeper object like so :

var myInput = ReactTestUtils.findRenderedDOMComponentWithClass(myComponent, 'myInput')

I get this error :

Invariant Violation: findAllInRenderedTree(...): instance must be a composite component at invariant (node_modules/fbjs/lib/invariant.js:44:15)

I cannot figure out what the type is that is returned from findRenderedDOMComponentWithClass because (a) Javascript and (b) ReactTestUtils has barely any documentation.

My entire test looks like this :

import ReactTestUtils from 'react-dom/lib/ReactTestUtils';

describe('simple test', function() {

  jsdom({ skipWindowCheck: true });

  it('Getting Simulate to Work', function() {
    class SomeComponent extends React.Component {
      render() {
        return (
          <div className="myComponent">
            <input type="textfield" className="myInput" ></input>
            <span className="child1" />
          </div>
        );
      }
    }
    var myDiv = ReactTestUtils.renderIntoDocument(
      <SomeComponent/>
    );
    var myComponent = ReactTestUtils.findRenderedDOMComponentWithClass(myDiv, 'myComponent')
    var myInput = ReactTestUtils.findRenderedDOMComponentWithClass(myComponent, 'myInput')
  });
});

Solution

  • You're getting that error because myInput isn't a composite component. It's a native browser input. Composite components are components made from React.Component (not divs, or spans, or inputs or buttons, etc).

    You could instead add a ref to your input:

    <input type="textfield" className="myInput" ref="myInput">
    

    and find it using React.findDOMNode:

    React.findDOMNode(this.refs.myInput)

    (where this here refers to an instance of the component containing the input, meaning in your case you'd need to call this inside the definition of SomeComponent somewhere).

    and then you should only use findRenderedDOMComponentWithClass to find components which are instances of React.Component (i.e. react components that you define as classes and register as a component with react with class SomeComponent extends React.Component).