我正在用Mocha和Enzyme测试反应成分。这是组件(为简化起见,已简化):
class New extends React.Component { // shortened for simplicity handleChange(event) { // handle changing state of input const target = event.target; const value = target.value; const name = target.name this.setState({[name]: value}) } render() { return( <div> <form onSubmit={this.handleSubmit}> <div className="form-group row"> <label className="col-2 col-form-label form-text">Poll Name</label> <div className="col-10"> <input className="form-control" ref="pollName" name="pollName" type="text" value={this.state.pollName} onChange={this.handleChange} /> </div> </div> <input className="btn btn-info" type="submit" value="Submit" /> </form> </div> ) } }
这是测试:
it("responds to name change", done => { const handleChangeSpy = sinon.spy(); const event = {target: {name: "pollName", value: "spam"}}; const wrap = mount( <New handleChange={handleChangeSpy} /> ); wrap.ref('pollName').simulate('change', event); expect(handleChangeSpy.calledOnce).to.equal(true); })
我期望当用户在<input>框中键入文本时,handleChange将调用该方法。上面的测试失败了:
<input>
handleChange
AssertionError: expected false to equal true + expected - actual -false +true at Context.<anonymous> (test/components/new_component_test.js:71:45)
我究竟做错了什么?
我应该澄清一下,我的目标是测试该方法handleChange是否被调用。我怎样才能做到这一点?
您可以直接通过原型直接监视该方法。
it("responds to name change", done => { const handleChangeSpy = sinon.spy(New.prototype, "handleChange"); const event = {target: {name: "pollName", value: "spam"}}; const wrap = mount( <New /> ); wrap.ref('pollName').simulate('change', event); expect(handleChangeSpy.calledOnce).to.equal(true); })
另外,您可以在实例的方法上使用间谍,但是您必须进行强制更新,因为在调用mount之后该组件已经呈现,这意味着onChange已绑定到其原始对象。
it("responds to name change", done => { const event = {target: {name: "pollName", value: "spam"}}; const wrap = mount( <New /> ); const handleChangeSpy = sinon.spy(wrap.instance(), "handleChange"); wrap.update(); // Force re-render wrap.ref('pollName').simulate('change', event); expect(handleChangeSpy.calledOnce).to.equal(true); })