簡體   English   中英

測試反應函數用Jest調用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM