用玩笑和酶测试自定义反应方法
testing custom react methods with jest and enzyme
我正在尝试在 React 组件中测试一个方法。该组件是一个表单,它应该测试在单击提交按钮时调用 handleSubmit() 方法。我试过下面的方法。
it('handlesSubmit when submit button is clicked', () => {
wrapper.find(Button).simulate('click');
expect(wrapper.instance().handleSubmit).toHaveBeenCalled();
})
这给出了错误 jest.fn() value must be a mock function or spy.
所以我尝试了这个:
it('handlesSubmit when submit button is clicked', () => {
const handleSubmit = jest.fn();
wrapper.find(Button).simulate('click');
expect(handleSubmit).toHaveBeenCalled();
})
这个错误说 Expected mock function to have been called
第一个块失败,因为 wrapper.instance().handleSubmit 不是一个开玩笑的模拟函数;它是 class 方法定义的任何内容。
第二个块失败了,因为 handleSubmit 虽然是一个开玩笑的模拟函数,但根本没有绑定到您的包装器组件。它是一个局部变量。当您模拟点击时,它再次调用实际实现。
为了完成你想要做的事情,你必须做这样的事情
it('handlesSubmit when submit button is clicked', () => {
const handleSubmit = jest.fn();
WrapperComponent.prototype.handleSubmit = handleSubmit;
const wrapper = shallow(<WrapperComponent />);
wrapper.find(Button).simulate('click');
expect(handleSubmit).toHaveBeenCalled();
})
其中 WrapperComponent 是您正在测试的组件。
以上应该可行,但有时您可以用更好的方式完成类似的事情。根据组件的实现,通常更容易测试调用 handleSubmit 方法中的功能而不是调用 handleSubmit 方法本身。例如,如果我的组件是
class TestComponent extends React.Component {
constructor(props) {
super(props)
this.state = { clicked: false }
this.onClick = this.onClick.bind(this)
}
onClick() {
this.props.onClick()
this.setState({ clicked: true })
}
render() {
return (
<button onClick={ this.onClick }>
{ 'Click Me' }
</button>
)
}
}
我可以通过
来测试它
it('calls onClick props and sets clicked state to true when clicked', () => {
const onClick = jest.fn();
const testComp = shallow(<TestComponent onClick={ onClick } />);
wrapper.find('button').simulate('click');
expect(onClick).toHaveBeenCalled();
expect(testComp.state('clicked')).toBe(true)
})
我一般更喜欢这种类型的测试,因为我不必覆盖原型,而且它实际上是在测试点击是否触发了我期望的逻辑。最初的测试实际上只涵盖了我将 this.handleSubmit 作为 onClick 道具传递给 Button 组件,仅此而已。
我正在尝试在 React 组件中测试一个方法。该组件是一个表单,它应该测试在单击提交按钮时调用 handleSubmit() 方法。我试过下面的方法。
it('handlesSubmit when submit button is clicked', () => {
wrapper.find(Button).simulate('click');
expect(wrapper.instance().handleSubmit).toHaveBeenCalled();
})
这给出了错误 jest.fn() value must be a mock function or spy.
所以我尝试了这个:
it('handlesSubmit when submit button is clicked', () => {
const handleSubmit = jest.fn();
wrapper.find(Button).simulate('click');
expect(handleSubmit).toHaveBeenCalled();
})
这个错误说 Expected mock function to have been called
第一个块失败,因为 wrapper.instance().handleSubmit 不是一个开玩笑的模拟函数;它是 class 方法定义的任何内容。
第二个块失败了,因为 handleSubmit 虽然是一个开玩笑的模拟函数,但根本没有绑定到您的包装器组件。它是一个局部变量。当您模拟点击时,它再次调用实际实现。
为了完成你想要做的事情,你必须做这样的事情
it('handlesSubmit when submit button is clicked', () => {
const handleSubmit = jest.fn();
WrapperComponent.prototype.handleSubmit = handleSubmit;
const wrapper = shallow(<WrapperComponent />);
wrapper.find(Button).simulate('click');
expect(handleSubmit).toHaveBeenCalled();
})
其中 WrapperComponent 是您正在测试的组件。
以上应该可行,但有时您可以用更好的方式完成类似的事情。根据组件的实现,通常更容易测试调用 handleSubmit 方法中的功能而不是调用 handleSubmit 方法本身。例如,如果我的组件是
class TestComponent extends React.Component {
constructor(props) {
super(props)
this.state = { clicked: false }
this.onClick = this.onClick.bind(this)
}
onClick() {
this.props.onClick()
this.setState({ clicked: true })
}
render() {
return (
<button onClick={ this.onClick }>
{ 'Click Me' }
</button>
)
}
}
我可以通过
来测试它it('calls onClick props and sets clicked state to true when clicked', () => {
const onClick = jest.fn();
const testComp = shallow(<TestComponent onClick={ onClick } />);
wrapper.find('button').simulate('click');
expect(onClick).toHaveBeenCalled();
expect(testComp.state('clicked')).toBe(true)
})
我一般更喜欢这种类型的测试,因为我不必覆盖原型,而且它实际上是在测试点击是否触发了我期望的逻辑。最初的测试实际上只涵盖了我将 this.handleSubmit 作为 onClick 道具传递给 Button 组件,仅此而已。