问题
I have a form with 3 radio buttons like follows (fake names):
<form className="myForm" onSubmit={this.done}>
<input className="myRadio" checked={ŧrue} type="radio" name="myRadio" onChange={this.change} value="value1"
<input className="myRadio" type="radio" name="myRadio" onChange={this.change} value="value2"
<input className="myRadio" type="radio" name="myRadio" onChange={this.change} value="value3"
<input type="submit" className="submit" />
</form>
And I am having very hard time trying to test the onChange and the onSubmit events.
inputs = TestUtils.scryRenderedDOMComponentsWithClass(MyComponentRendered, 'myRadio');
myForm = TestUtils.findRenderedDOMComponentWithClass(MyComponentRendered, 'myForm');
I have a test like:
it("changes the checked state when clicked", function() {
MyComponent.change = jest.genMockFunction();
expect(inputs[0].getDOMNode().checked).toBe(true);
TestUtils.Simulate.change(inputs[1], {target: {value: 'value2'}});
expect(inputs[0].getDOMNode().checked).toBe(false);
expect(inputs[1].getDOMNode().checked).toBe(true);
expect(inputs[2].getDOMNode().checked).toBe(false);
expect(MyComponent.change).toBeCalled(); //Fails
expect(MyComponent.change.mock.calls.length).toBe(1); //Fails too
});
That works except for the function (MyComponent.change) that should be called but it is not.
I also have one test for onSubmit:
it("saves on submit", function()
MyComponent.done = jest.genMockFunction();
MyComponent.insideDone = jest.genMockFunction();
TestUtils.Simulate.submit(myForm);
expect(MyComponent.done).toBeCalled(); //Fails
expect(MyComponent.insideDone).toBeCalled(); //Success
});
Notice: MyComponent.insideDone is a function that is called by 'done' function.
Which fails too. I am pretty sure that the problem here is that I am not simulating the events in a correct way. However, I didn't find example of this using Jest and TestUtils from React.
回答1:
The problem is that you are replacing the function after you have already given the original function to React. The expression onSubmit={this.done}
is that function, and that is set as the event handler. After the render function finishes, you replace instance.done
but React already got the old function. What you should do is instead:
<form className="myForm" onSubmit={() => this.done()}>
This makes sure that the event handler always invokes the method on the instance (the one you replaced). This has the nice side effect of being future compatible with React, since they will stop autobinding all methods to the instance.
来源:https://stackoverflow.com/questions/26470679/test-a-form-with-jest-and-react-js-testutils