如何使用 Jest 和 Enzyme 对包含 history.push 的反应事件处理程序进行单元测试?
How to unit test a react event handler that contains history.push using Jest and Enzyme?
给定一个简单的组件:
export default class SearchForm extends Component {
constructor(props) {
super(props)
this.state = { query: '' }
}
onSubmit = (event) => {
event.preventDefault()
history.push(`/results/${this.state.query}`, { query: this.state.query })
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input
type="text"
value={this.state.query}
onChange={event => this.setState({ query: event.target.value })}
/>
<button>Search</button>
</form>
)
}
}
测试:
describe('SearchForm Component', () => {
it('should navigate to results/query when submitted', () => {
const wrapper = shallow(<SearchForm />)
...?
})
})
您如何验证表单提交是否将用户带到具有正确查询值的下一页?
我试过简单地模拟 onSubmit 处理程序并至少确认它已被调用,但这会导致安全错误,原因是 history.push
。
const wrapper = shallow(<SearchForm />)
const mockedEvent = { target: {}, preventDefault: () => {} }
const spy = jest.spyOn(wrapper.instance(), 'onSubmit')
wrapper.find('form').simulate('submit', mockedEvent)
expect(spy).toHaveBeenCalled()
其实很简单,你可以在测试中浅渲染的时候给组件传入任何props,像这样:
const wrapper = shallow(<SearchForm history={historyMock} />)
顺便说一句,在onSubmit
里面,你应该像this.props.history.push(...)
一样调用。
现在,要创建一个 mock(更多信息在 documentation),你可以在测试中这样写:
const historyMock = { push: jest.fn() };
请记住,你实际上只是在模拟 history
对象的 push
方法,如果你在组件内部使用更多方法并想测试它们,你应该创建一个模拟来每一个都经过测试。
然后,您需要断言 push
模拟已被正确调用。为此,您编写必要的断言:
expect(historyMock.push.mock.calls[0]).toEqual([ (url string), (state object) ]);
使用需要的 (url string)
和 (state object)
进行断言。
给定一个简单的组件:
export default class SearchForm extends Component {
constructor(props) {
super(props)
this.state = { query: '' }
}
onSubmit = (event) => {
event.preventDefault()
history.push(`/results/${this.state.query}`, { query: this.state.query })
}
render() {
return (
<form onSubmit={this.onSubmit}>
<input
type="text"
value={this.state.query}
onChange={event => this.setState({ query: event.target.value })}
/>
<button>Search</button>
</form>
)
}
}
测试:
describe('SearchForm Component', () => {
it('should navigate to results/query when submitted', () => {
const wrapper = shallow(<SearchForm />)
...?
})
})
您如何验证表单提交是否将用户带到具有正确查询值的下一页?
我试过简单地模拟 onSubmit 处理程序并至少确认它已被调用,但这会导致安全错误,原因是 history.push
。
const wrapper = shallow(<SearchForm />)
const mockedEvent = { target: {}, preventDefault: () => {} }
const spy = jest.spyOn(wrapper.instance(), 'onSubmit')
wrapper.find('form').simulate('submit', mockedEvent)
expect(spy).toHaveBeenCalled()
其实很简单,你可以在测试中浅渲染的时候给组件传入任何props,像这样:
const wrapper = shallow(<SearchForm history={historyMock} />)
顺便说一句,在onSubmit
里面,你应该像this.props.history.push(...)
一样调用。
现在,要创建一个 mock(更多信息在 documentation),你可以在测试中这样写:
const historyMock = { push: jest.fn() };
请记住,你实际上只是在模拟 history
对象的 push
方法,如果你在组件内部使用更多方法并想测试它们,你应该创建一个模拟来每一个都经过测试。
然后,您需要断言 push
模拟已被正确调用。为此,您编写必要的断言:
expect(historyMock.push.mock.calls[0]).toEqual([ (url string), (state object) ]);
使用需要的 (url string)
和 (state object)
进行断言。