测试传递给 Redux HOC 的强制 PropTypes
Posted
技术标签:
【中文标题】测试传递给 Redux HOC 的强制 PropTypes【英文标题】:Testing mandatory PropTypes passed to Redux HOC's 【发布时间】:2019-04-16 11:35:32 【问题描述】:我想编写一个测试,以确保反应组件将具有propType.isRequired
的道具传递给子组件。
如果未提供道具,我希望此测试失败,如果提供,则通过。我正在使用jest-prop-type-error
在我的测试中抛出错误。
给定以下两个组件:
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)
我想确保我的 Parent
组件通过 childTitle
属性,而无需编写显式测试:
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()
)
请注意以下几点:
如果 child 不是connect
ed 组件,我可以 not
将 childTitle
传递给 Parent
并且测试将失败。由于它是一个连接组件,如果我没有通过childTitle
,则测试通过(即使在ReduxChild
中是必需的)
我知道这非常接近于测试PropTypes
的功能,但它的细微差别在于我想检查Parent
是否正确使用Child
,而不是ReduxChild
抛出一个PropTypes未通过道具时出错。我希望测试在开发人员删除所需道具时在构建时失败,而不是在我运行代码时在运行时失败。
编辑:
为了进一步说明这个问题,如果我有第二个子组件 NonReduxChild
并给它一个 propType
其中 isRequired
并测试 Parent
渲染 NonReduxChild
而没有提供我得到的道具在构建/测试时抛出错误。 ReduxChild
我没有。
NonReduxChild.js
const NonReduxChild = ( text ) = <div>text</div>
NonReduxChild.propTypes = text: PropTypes.string.isRequired
测试输出
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 |
正如您从测试输出中看到的那样,当我没有向 NonReduxChild
提供所需的道具时,我得到一个测试失败,它很好地从其他可能不提供所需 PropTypes
的组件中捕获了 NonReduxChild
的使用情况我没有从ReduxChild
得到同样的失败我必须编写一个特定的测试(我不想在包含数百个组件的代码库中这样做)。
【问题讨论】:
不清楚为什么确保我的 Parent 组件通过 childTitle 属性而不需要编写明确的测试,说明是一项要求。这是对组件进行单元测试的正确方法。 嗯,这是因为我不想在整个大型应用程序中使用Child
组件的每个 Parent
组件上测试每个道具。正如我在笔记中提到的,如果Child
不是connect()
ed 组件,并且我的应用程序代码没有通过isRequired
属性,那么任何Parent
测试都会失败,而无需我编写显式测试。
你说得对,这可能更像是一个集成测试。我会更新标签。在单元测试方面,Child
组件确实对每个必需的道具进行了测试,因此涵盖了事物的一面。 Child
所需的未提供的 propType 将在运行时在浏览器中爆炸,而不是在我所追求的构建时爆炸,如果您愿意,我可以更新问题以演示非 redux 如何如果这样可以使事情更清晰,连接的组件会以相同的设置运行吗?
我可以更新问题以演示非 redux 连接的组件在相同设置下的行为,如果这样可以使事情更清晰? 是的,这很好。到时候我会尽量给出答案。
@estus - 我已经更新以显示 NonReduxChild
的行为方式
【参考方案1】:
我相信您遇到的问题是 PropTypes 只是记录警告,这实际上不会导致测试失败。
如果道具对组件的操作至关重要,并且您设置不编写测试来断言道具存在,那么如果该道具不存在,您总是可以让组件抛出错误。这将导致测试失败。
【讨论】:
感谢您的回复,但我使用jest-prop-type-error
在测试中抛出错误,这也没有解决父 > 子问题,也没有解决 redux 与非 redux 子差异【参考方案2】:
我认为您可以将 title 定义为 prop 并且您可以调用它,而不是 "childTitle"
。
试试这个..它可能会工作
it('should send the required "title" prop to ReduxChild', () =>
`var wrapper = shallow(<Parent renderReduxChild=true title="expectedTitle" />);`
expect(wrapper.props().title).toBeDefined()
`console.log("",childTitle);`
)
【讨论】:
感谢您的贡献,但我不确定您的回答是否解决了问题以上是关于测试传递给 Redux HOC 的强制 PropTypes的主要内容,如果未能解决你的问题,请参考以下文章
Jest/Enzyme 单元测试:如何将存储传递给使用 redux 4 和 react-redux 6 连接功能的浅层组件