我有一个React类,它呈现一个名为PersonalDetails的子组件。代码工作正常,但是当在字段中按Enter键时,我无法让Jest验证是否正确调用了saveData。我已经模拟了传递给PersonalDetails的saveData函数,但是在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)
}
}
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");
});
我在这里缺少什么想法?
答案 0 :(得分:0)
你可以创建一个间谍。间谍是间谍,即保持跟踪。使用间谍,你可以检查功能是否被调用。
示例代码(从网上复制)
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
答案 1 :(得分:0)
问题的原因很简单但很难发现:
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
,即可调用处理程序。
度过美好的一天!