I would like to write a test which ensures that a react component passes a prop which has propType.isRequired to a child component.
I would like this test to fail if the prop is not provided and pass if it is. I'm using jest-prop-type-error to throw errors in my tests.
Given the following two components:
Parent.js
const Parent = ({ renderReduxChild , childTitle }) =>
{ return renderReduxChild ? <ReduxChild title={childTitle} /> : <NonReduxChild />}
ReduxChild.js
const ReduxChild = ({ title }) => <div>{title}</div>
ReduxChild.propTypes = { title: PropTypes.string.isRequired }
export default connect(mapStateToProps, mapStateToProps)(ReduxChild)
I would like ensure my Parent component passes the childTitle prop without needing to write an explicit test which says:
Parent.test.js
it('should send the required "title" prop to ReduxChild', () => {
const wrapper = shallow(<Parent renderReduxChild={true} childTitle={'expectedTitle'} />)
expect(wrapper.props().title).toBeDefined()
})
Please note the following:
- If child was not a
connected component, I couldnotpasschildTitletoParentand the test would fail. Since it is a connected component, if I don't passchildTitlethe test passes (even though it's required inReduxChild) - I'm aware that this is quite close to testing the functionality of
PropTypes, but it's subtly different in that I want to check thatParentis usingChildcorrectly, not thatReduxChildthrows a PropTypes error when the prop isn't passed. I want the test to fail at build time when a dev removes the required prop, not at runtime when I exercise the code.
EDIT:
To further illustrate the issue, if I have a second child component NonReduxChild and give it a propType which isRequired and have a test for Parent which renders the NonReduxChild without providing the prop I get an error thrown at build / test time. Wheres with the ReduxChild I do not.
NonReduxChild.js
const NonReduxChild = ({ text }) = <div>{text}</div>
NonReduxChild.propTypes = { text: PropTypes.string.isRequired }
Test output
FAIL test/components/Parent.test.js (8.782s)
● <Parent /> › when rendering the component › if renderReduxChild is false it should render <NonReduxChild />
Warning: Failed prop type: The prop `title` is marked as required in `NonReduxChild`, but its value is `undefined`.
in NonReduxChild
28 | render() {
29 | const { renderReduxChild, childTitle } = this.state
> 30 | return renderReduxChild ? <ReduxChild title={childTitle } /> : <NonReduxChild />
| ^
31 | }
32 | }
33 |
As you can see from the test output, when I don't provide a required prop to NonReduxChild I get a test failure which nicely captures the usage of NonReduxChild from other components which might not provide required PropTypes I don't get this same failure from ReduxChild I have to write a specific test (which I don't want to do across a codebase with hundreds of components).