vendredi 25 mars 2016

Testing React Function was Called with Jest

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?

Aucun commentaire:

Enregistrer un commentaire