[英]Testing React Function was Called with Jest
我有一个React类,它呈现一个名为PersonalDetails的子组件。 代码工作正常,但是当在字段中按Enter键时,我无法让Jest验证是否正确调用了saveData。 我已经模拟了传递给PersonalDetails的saveData函数,但是模拟上的断言失败了(代码简称为简洁):
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)
}
}
PersonalDetails模块如下:
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测试案例:
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");
});
我在这里缺少什么想法?
你可以创建一个间谍。 间谍会进行间谍活动,即保持跟踪。使用间谍,您可以检查该功能是否被调用。
示例代码(从网上复制)
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
您的问题的原因很简单但很难发现:
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();
});
将此与您问题中的解决方案进行比较。
对于输入元素,您使用onKeyPress
事件,但在测试中您模拟了无法工作的keyDown
,只需将其替换为keyPress
调用处理程序。
祝你今天愉快!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.