I have a React class which renders a child component called PersonalDetails. The code works fine, however I cannot get Jest to verify the saveData was called correctly when the Enter key is pressed in the field. I have mocked the saveData function passed to the PersonalDetails but the assertions fail (code condensed for brevity) on the mock:
class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
name: null
};
this.saveData = this.saveData.bind(this);
}
render() {
return (
<div>
<PersonalDetails name={this.state.name} saveData={this.saveData}/>;
<OtherThing saveData={this.saveData}/>
</div>
)
}
saveData(key, value){
var d = {};
d[key] = value;
this.setState(d)
}
}
The PersonalDetails module is as follows:
class PersonalDetails extends React.Component {
constructor(props) {
super(props);
this.handleNameChange = this.handleNameChange.bind(this);
}
render() {
return (
<div>
<input onKeyPress={this.handleNameChange}
defaultValue={this.props.name}/>
</div>
)
}
handleNameChange(event) {
if (event.nativeEvent.keyCode != 13) return;
this.props.saveData('name',event.target.value)
}
}
Jest test case in question:
it("saves data on change", function () {
var saveData = jest.genMockFunction(); // mocking saveData
const pdComponent = TestUtils.renderIntoDocument(
<PersonalDetails saveData={saveData} name="My Name"/>
);
var input = TestUtils.findRenderedDOMComponentWithTag(
pdComponent, 'input'
);
var node = ReactDOM.findDOMNode(input);
node.value = "New Name"; // As per FB tests
TestUtils.Simulate.change(node, {target: {value: "New Name"}});
TestUtils.Simulate.keyDown(node, {key: "Enter", keyCode: 13, which: 13});
expect(node.value).toBe("New Name"); // Passes
// Fails
expect(pdComponent.props.saveData).toBeCalledWith("New Name");
// Also Fails
expect(saveData).toBeCalledWith("New Name");
});
Any ideas what I'm missing here?
You can create a Spy. A spy would be spying ie keeping track.Using the Spy, you can check if the function was called or not.
Sample Code( Copied from the net)
var CompSpec = {
displayName: "Comp",
plop: function() {
console.log("plop");
},
render: function() {
this.plop();
return React.DOM.div("foo");
}
};
var stub = sinon.stub(CompSpec, "plop");
var Comp = React.createClass(CompSpec);
React.addons.TestUtils.renderIntoDocument(Comp());
// plop() is properly stubbed, so you can
sinon.assert.called(stub); // pass
The cause of your problem is simple yet difficult to discover:
it('just an input test', () => {
const keyPressAction = jest.fn(() => {
console.log('key press');
});
const input = TestUtils.renderIntoDocument(<input type="text" onKeyPress={keyPressAction.bind(this)}/>);
const inputNode: Element = ReactDOM.findDOMNode(input);
inputNode.setAttribute('value', 'test');
TestUtils.Simulate.keyPress(inputNode, {key: "Enter", keyCode: 13, which: 13});
expect(input.getAttribute('value')).toEqual('test');
expect(keyPressAction).toBeCalled();
});
Compare this with the solution in your question.
For the input element you use onKeyPress
event, but in the test you simulate keyDown
which can't work, just replace it with keyPress
and the handler will be called.
Have a nice day!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.