我有一个组件可以加载另一个组件,并向它发送一个匿名函数作为道具:
export class Header extends Component {
constructor(props) {
super(props)
this.state = { activeTab: TAB_NAMES.NEEDS_REVIEW }
}
filterByNeedsReview() {
const { filterByNeedsReviewFn } = this.props
this.setState({ activeTab: TAB_NAMES.NEEDS_REVIEW })
filterByNeedsReviewFn()
}
...
render() {
return (
<Container>
...
...
<FilterTab
active={this.state.activeTab === TAB_NAMES.NEEDS_REVIEW}
name={TAB_NAMES.NEEDS_REVIEW}
count={40}
onClick={() => this.filterByNeedsReview()}
/>
...
...
</Container>
)
}
}
我的测试失败:
it('renders a filter tab with the right props for needs review', () => {
const filterByNeedsReviewFn = jest.fn()
expect(
shallowRender({ filterByNeedsReviewFn })
.find(FilterTab)
.findWhere(node =>
_.isMatch(node.props(), {
active: true,
name: 'Needs Review',
count: 40,
onClick: filterByNeedsReviewFn, //<-------------- THIS DOESN'T WORK
})
)
).toHaveLength(1)
})
我该如何测试onClick
是对的?
答案 0 :(得分:1)
我相信您不需要检查内部事件处理程序的外观。您可能对其他事情感兴趣:如果触发事件处理程序按预期更改了组件({.toMatchSnapshot()
在这里要好得多,而不是使用.toHaveLength
手动测试结构),并且如果回调已经通过{{1 }}应该在(props
时被调用。如果某天更改了组件,不仅要调用.toHaveBeenCalled
,还要做一些诸如调用其他任何事情的事情怎么办?您的测试是否会因为内部传递了命名方法而失败?我相信不是。
所以我认为您的考验是
.props.filterByNeedsReviewFn()
我认为您实际上并不需要此代码,但我想说明这种方法有多清晰。您的组件具有API:调用它的props回调并呈现输出。因此,我们可以跳过内部测试而没有任何陷阱