Unsure if this also impacts in a browser. I wrote an example of this here: https://github.com/iamdustan/react-testing-stateless-components
I wrote two components. One with class Component extends React.Component and the other var Component = (props) => ().
The test case is identical for each. The class component test passes. The function component test fails.
_https://github.com/iamdustan/react-testing-stateless-components/blob/master/class.js_
import React from 'react';
class Component extends React.Component {
render() {
var {onClick, text} = this.props;
return (
<button onClick={onClick}>{text}</button>
);
}
};
Component.propTypes = {
onClick: React.PropTypes.func.isRequired,
text: React.PropTypes.string.isRequired,
};
export default Component;
_https://github.com/iamdustan/react-testing-stateless-components/blob/master/stateless.js_
import React from 'react';
var Component = ({onClick, text}) => (
<button onClick={onClick}>{text}</button>
);
Component.propTypes = {
onClick: React.PropTypes.func.isRequired,
text: React.PropTypes.string.isRequired,
};
export default Component;
_Output_
Using Jest CLI v5.0.3
FAIL __tests__/stateless-test.js (0.998s)
● thing › it render
- TypeError: Cannot read property 'textContent' of null
at Spec.<anonymous> (/Users/dkasten/projects/react-test-case/__tests__/stateless-test.js:15:34)
at jasmine.Block.execute (/Users/dkasten/projects/react-test-case/node_modules/jest-cli/vendor/jasmine/jasmine-1.3.0.js:1065:17)
at jasmine.Queue.next_ (/Users/dkasten/projects/react-test-case/node_modules/jest-cli/vendor/jasmine/jasmine-1.3.0.js:2098:31)
at null._onTimeout (/Users/dkasten/projects/react-test-case/node_modules/jest-cli/vendor/jasmine/jasmine-1.3.0.js:2088:18)
at Timer.listOnTimeout (timers.js:89:15)
PASS __tests__/class-test.js (1.109s)
1 test failed, 1 test passed (2 total)
This failure is not due to interactions with Jest as it also exists on another project that is not using Jest (although still using jsdom).
The test (to save a couple clicks):
it('render', function() {
var React = require('react');
var findDOMNode = require('react-dom').findDOMNode;
var StatelessComponent = require('../stateless');
var TestUtils = require('react/lib/ReactTestUtils');
var spy = jasmine.createSpy();
var component = TestUtils.renderIntoDocument(
<StatelessComponent text="Hello" onClick={spy} />
);
expect(findDOMNode(component).textContent).toBe('Hello');
});
I would also expect this to work… cc @spicyj
I _almost_ copied everything into here. Thanks @zpao.
I haven’t hit any issues with stateless components and the shallow renderer, yet.
Stateless components have no public instance. If you were to wrap it in another (stateful) composite then you could call findDOMNode on that component.
cc @sebmarkbage for verification
I moved the stateless currently failing approach to wrap it in a <div /> with the test utils. From this I can get to testing what I want, but it’s a bit awkward.
var component = TestUtils.renderIntoDocument(<div><StatelessComponent ... /></div>);
var statelessComponent = findDOMNode(component).children[0];
https://github.com/iamdustan/react-testing-stateless-components/blob/master/__tests__/stateless-failure-test.js
https://github.com/iamdustan/react-testing-stateless-components/blob/master/__tests__/stateless-success-test.js
Is there a better way of doing this that I’m unaware of? Or is this just the way it is going to be for a while?
You can use Shallow testing to avoid needing to reach into the DOM:
https://facebook.github.io/react/docs/test-utils.html#shallow-rendering
How do you test event handling with the shallow renderer? E.g. TestUtils.Simulate.*? (E.g. https://github.com/iamdustan/react-testing-stateless-components/blob/master/__tests__/stateless-success-test.js#L29-L30)
Are refs and Stateless Components also not 100% compatible with standard components? From what I can tell refs are always null for a stateless component...
If you came here wondering about refs and Stateless Components take a look at https://github.com/facebook/react/issues/4936.
@iamdustan Right now it seems you cannot test event handling with the shallow renderer. At least that is what I gather from #1445.
I'm having this same issue while trying to test stateless components (renderIntoDocument is returning nil). It looks like wrapping it in <div> does help, but this does seem to be an awkward fix.
Has there been any progress on this issue?
One way to avoid 'null' or the TestUtils altogether when testing event handlers is to instantiate the component as a constructor (i.e. var comp = new MyComp(props) ).
Interesting find from this article.
I can confirm that using the new keyword resolved this issue for me. Any chance there's some progress on this issue? It looks ugly and my team is totally mess this up and le tests will not get written :(
Closing as works by design. If you end up here read #4936 for more information.
Most helpful comment
One way to avoid 'null' or the TestUtils altogether when testing event handlers is to instantiate the component as a constructor (i.e. var comp = new MyComp(props) ).
Interesting find from this article.