简体   繁体   English

测试反应函数用Jest调用

[英]Testing React Function was Called with Jest

I have a React class which renders a child component called PersonalDetails. 我有一个React类,它呈现一个名为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. 代码工作正常,但是当在字段中按Enter键时,我无法让Jest验证是否正确调用了saveData。 I have mocked the saveData function passed to the PersonalDetails but the assertions fail (code condensed for brevity) on the mock: 我已经模拟了传递给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)
    }
}

The PersonalDetails module is as follows: 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 test case in question: 有问题的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");

});

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. 对于输入元素,您使用onKeyPress事件,但在测试中您模拟了无法工作的keyDown ,只需将其替换为keyPress调用处理程序。

Have a nice day! 祝你今天愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM