If I have a render prop component like so:
export class ParentComponent extends React.Component {
render() {
<Loader loading={false}>
{() =>
<SomeChildComponent />
}
}
}
How can I unit test it?
test('should output child component', => {
const wrapper = shallow(<ParentComponent />);
expect(wrapper.find(SomeChildComponent).length).to.be(1);
}
Fails - If I test for the Loader component instead - the test passes:
expect(wrapper.find(Loader).length).to.be(1);
How can I test that SomeChildComponent is output?
Testing The ParentComponent is Setting Props Correctlyrender(<ParentComponent open data="some data" />); // Check that the Jest mock function is called with an object. // Use 'expect. objectContaining' to make sure any other default // React props are ignored. expect(mockChildComponent). toHaveBeenCalledWith( expect.
Using React DevTools to highlight what components rerendered To enable it, go to "Profiler" >> click the "Cog wheel" on the right side of the top bar >> "General" tab >> Check the "Highlight updates when components render." checkbox.
The term “render prop” refers to a technique for sharing code between React components using a prop whose value is a function. In simple words, render props are simply props of a component where you can pass functions. These functions need to return elements, which will be used in rendering the components.
Your inner function () =><SomeChildComponent />
never executed, so your test says the truth that SomeChildComponent
does not exists. You just need to call it (notice extra brackets):
export class ParentComponent extends React.Component {
render() {
return (<Loader loading={false}>
{ (() =><SomeChildComponent />)()}
</Loader>);
}
}
We can refactor it into more render-props way:
export class ParentComponent extends React.Component {
render() {
return (<Loader loading={false}>
{ this.props.render()}
</Loader>);
}
}
And then change the test accordingly:
const render = () => <SomeChildComponent />;
const wrapper = shallow(
<ParentComponent render={render} />
);
However, this test becomes not really a unit
test, as it tests more then one component at once. To get rid of this dependency we can just check if render()
is called:
const renderMock = jest.fn();
const wrapper = shallow(<ParentComponent render={ renderMock } />);
expect(wrapper.find('Loader').exists()).toBeTruthy();
expect(renderMock).toHaveBeenCalled();
If your render()
accepts some arguments you can consider using .toHaveBeenCalledWith
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With