javascript - 测试 React 组件回调到父组件的好方法是什么?

标签 javascript testing meteor reactjs

我目前正在转向更多的 TDD 方法,并希望在测试 React 组件方面做得更好。在测试 React 组件时,我遇到的一个问题是测试子组件到父组件的回调。

什么是测试内部 React 组件通信的有效方法,例如父组件的回调?

this question的回应似乎提供了一个可能的解决方案,尽管我不太理解它(例如,我并不完全熟悉如何在 Jasmine 测试中使用函数链接。)

提前感谢您的任何提示和建议!

示例

(以下示例使用 Meteor,但我不一定要寻找特定于 Meteor 的解决方案。)

Repo with the complete example .

假设我有一个接受文本输入并在提交时通过 props 传递它的组件:

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>
    )
  }
});

然后,我的(Jasmine)测试看起来像这样。测试通过。然而,似乎应该有一种更简单的方法来做到这一点......

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);
  });

});

最佳答案

一种不需要父组件的方法是使用 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);
  });

});

关于javascript - 测试 React 组件回调到父组件的好方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35491361/

相关文章:

ruby-on-rails - 禁用 rake 数据库 :test:prepare while using cucumber rails

meteor - 如何禁止拥有 Meteor 帐户的人?

javascript - Meteor移动应用-嵌入式数据库

javascript - Srcset 似乎不适用于 iOS7 中的移动 safari?

javascript - 在 for 循环中使用 Angular 的 $timeout 执行方法

JavaScript 正则表达式查找字符串

javascript - 如何使用 Meteor 空格键模板和每行的行号渲染表格?

javascript - Xpath:获取节点属性

.net - VS 2015移动文件后无法运行发布

Laravel 事件触发但 PHPUnit 未检测到它被触发