Testing functional components with renderIntoDocument

I am involved in testing stateless, stateless components using the ReactTestUtils library. This is my simple component:

import React from 'react'; const Greeter = ({name,place}) => ( <h1>Hello,{name}. Welcome to the {place}.</h1> ); export default Greeter; 

This is my test spec, to get renderIntoDocument working, I wrapped my Greeter component in a div, as suggested here :

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

I get an error

findAllInRenderedTree (...): the instance must be a composite component.

I provide my code as jsbin here .

+6
source share
3 answers

Since functional components do not have an instance associated with them, you cannot use them directly with render or renderIntoDocument. Trying to wrap a functional component is a good idea, unfortunately, using a div does not work for the same reason. DOM components also do not return a component instance; instead, they return the base DOM node.

This is all that can be said that you cannot use the test utility or your own components as the "root" component that you are running. Instead, you'll want to wrap your functional components in a shell component that uses createClass or extends React.Component .

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

Gotcha, as this may be reason enough to use a third-party test library, such as a popular enzyme, or my own: teaspoon . Both abstract on issues such as wrapping and deploying functional components seamlessly for you, so you donโ€™t have to worry about what type of component you are trying to make.

+12
source

The functional packaging components in the <div> work for me. You just need to find the component that you want to test a little differently, i.e.

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

note that for testing you can use myNode using cpt.childNodes[0]

0
source

To improve @ monastic-panic's answer, my two cents:

You do not need to create a class for this. Do it dynamically:

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

All Articles