2016-02-18 54 views
3

我目前正朝着更多TDD方法邁進,並希望在測試React組件方面做得更好。測試React組件的一個方面就是測試一個子組件對父組件的回調。什麼是測試React組件回調到父組件的好方法?

什麼是測試內部React組件通信的有效方式,比如對父組件的回調?

this question的反應似乎提供了一個可能的解決方案,但我不明白它(例如,我不完全熟悉如何在茉莉花測試使用功能鏈接。)提前

謝謝任何提示和建議!

(以下示例使用流星,雖然我不一定要找特定流星的解決方案。)

Repo with the complete example

比方說,我有一個不接受文本輸入,並通過道具將其傳遞提交組件:

SingleFieldSubmit = React.createClass({ 
    propTypes: { 
    handleInput: React.PropTypes.func.isRequired 
    }, 
    getDefaultProps() { 
    return { 
     inputValue: "" 
    }; 
    }, 
    getInitialState() { 
    return { 
     inputValue: this.props.inputValue 
    }; 
    }, 
    updateInputValue(e){ 
    this.setState({inputValue: e.target.value}); 
    }, 
    handleSubmit(e) { 
    e.preventDefault(); 
    this.handleInput(); 
    }, 
    handleInput(){ 
    this.props.handleInput(this.state.inputValue.trim()); 
    }, 
    render() { 
    return (
     <form className="single-field-submit" onSubmit={this.handleSubmit}> 
     <input 
      type="text" 
      value={this.state.inputValue} 
      onChange={this.updateInputValue} 
     /> 
     </form> 
    ) 
    } 
}); 

在這裏,我想如果組件傳遞提交用戶輸入進行測試。我現在,有點笨重,解決方案是創建一個模擬父組件與組件我想測試包括作爲一個孩子:

MockParentComponent = React.createClass({ 
    getInitialState: function() { 
    return { 
     callbackValue: null 
    }; 
    }, 
    handleCallback: function(value) { 
    this.setState({callbackValue: value}); 
    }, 
    render: function() { 
    return (
     <div className="container"> 
     <SingleFieldSubmit handleInput={this.handleCallback} /> 
     </div> 
    ) 
    } 
}); 

然後,我(茉莉花)測試看起來是這樣的。測試通過。但是,好像應該有這樣的一個簡單的方法....

describe('SingleFieldSubmit Component', function() { 

    it('should, on submit, return the value input into the form', function() { 

    //SETUP 
    let mockUserInput = 'Test input'; 
    let parentComponent = TestUtils.renderIntoDocument(
      React.createElement(MockParentComponent) 
     ); 
    let node  = ReactDOM.findDOMNode(parentComponent); 
    let $node = $(node); 
    expect(parentComponent.state.callbackValue).toBe(null); 

    //TEST 
    Simulate.change($node.find('input')[0], { target: { value: mockUserInput } }); 
    Simulate.submit($node.find('form')[0]); 
    expect(parentComponent.state.callbackValue).toBe(mockUserInput); 
    }); 

}); 

回答

6

一個不需要父組件的方法是使用jasmine spies

describe('SingleFieldSubmit Component', function() { 

    it('should call handleInput prop with value of the input on submit', function() { 

    //SETUP 
    let callbackSpy = jasmine.createSpy('callbackSpy'); 
    let mockUserInput = 'Test input'; 
    let component = TestUtils.renderIntoDocument(<SingleFieldSubmit handleInput={callbackSpy} />); 
    let form = TestUtils.findRenderedDOMComponentWithTag(component, 'form'); 
    let input = TestUtils.findRenderedDOMComponentWithTag(component, 'input') 

    //TEST 
    Simulate.change(imput, { target: { value: mockUserInput } }); 
    Simulate.submit(form); 
    expect(callbackSpy).toHaveBeenCalledWith(mockUserInput); 
    expect(callbackSpy.calls.count()).toEqual(1); 
    }); 

}); 
+0

這是一個重大的改進。謝謝!此外,謝謝你包含一個findRenderedDOMComponentWithTag的例子,我將開始使用向前移動。 (我使用此解決方案更新了上面的回購。) – andersr

相關問題