在 Jest 中调用 React 的 this.props.onClick(this) 时我到底应该测试什么?

What exactly should I test when calling React's this.props.onClick(this) in Jest?

我一直在为我的所有事件(当然还有其他所有事件)编写测试,但我不知道如何测试 this.props.onClick(this) 在 child 成分。

我的 child 组件具有以下代码:

closeModal: function() {
  this.props.onClick(this);
},

render: function() {
  return (
    <i className="close-icon" onClick={this.closeModal}></i>
  )
}

parent 正在这样听:

onCloseModal: function() {
  this.replaceState({
    modalStatus: 'hidden'
  });
},

render: function() {
  return (
    <QuestionModal modalStatus={this.state.modalStatus} onClick={this.onCloseModal} />
  )
}

我知道如何测试 parent 的点击事件,我也知道如何在测试中调用 child 的按钮点击事件,但我不确定我要做什么应该是准确的测试。

如果我使用 Sinon 和 Jasmine,我会存根 closeModal 方法并检查它是否被调用。我可以用 Jest 做到这一点吗?如果可以,具体怎么做?

更新

我已经尝试根据@PhilVarg 的回答编写一个测试,但我没有走得很远,因为我无法模拟 closeModal

这是我的测试:

      var closeIcon,
          myMock = jest.genMockFunction();

      form = TestUtils.renderIntoDocument(
        <QuestionForm />
      );
      form.closeModal = myMock;

      closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');

      TestUtils.Simulate.click(closeIcon);

      expect(form.closeModal).toBeCalled();

预期函数被调用的测试错误。 和 closeModal 没有模拟但仍在运行(我现在有一个控制台登录)。我整个下午都在研究它,但一直无法弄清楚。任何帮助将不胜感激。

如果你想检查函数是否被调用你想使用 jest 的 toBeCalled function (or toBeCalledWith). Assuming you've done some set up to instantiate the components, renderIntoDocument, and simulate the click (checkout the tutorial 如果没有)

describe('#closeModal', function(){
  beforeEach(function(){
    // setup in here to instantiate / render component 
    // and simulate the click if the i tag
  })
  it('is called on click', function(){
    expect(questionModal.closeModal).toBeCalled()
  })
})

编辑: 好的,所以在修补它之后,我能够通过类似于您的原始结构的测试来进行测试。我创建了一个模拟函数,但我没有做 form.closeModal = mock,而是将模拟作为 onClick 道具传递给问题,并检查它是否被调用。

describe('#closeModal', function(){
  var mock, form, closeIcon;

  beforeEach(function(){
    mock = jest.genMockFunction();
    form = TestUtils.renderIntoDocument(
      <QuestionForm onClick={ mock } />
    );
    closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');
    TestUtils.Simulate.click(closeIcon);
  })

  it('is called on click', function(){
    expect(mock).toBeCalled()
  })
})

您可以使用异步测试。您必须在 onClick 处理程序中调用 done()。如果一切正常,处理程序将调用 done() 并且测试通过。如果处理程序不会被调用,则测试会在一段时间后失败,因为 Jasmine 无法结束它。

无需存根或嘲笑。

it('should click', function(done) {
  function onClick() {
    done();
  }
  var instance = TestUtils.renderIntoDocument(
    <Component onClick={onClick} />
  );
  var button = TestUtils.findRenderedDOMComponentWithTag(instance, 'button');
  var buttonDOM = React.findDOMNode(button);
  React.addons.TestUtils.Simulate.click(buttonDOM);
});

感谢菲尔的一些建议,我终于弄明白了。我要测试的是单击图标时调用 closeModal。我已经测试过父组件的行为符合预期,但我不知道如何模拟 closeModal,因为我正在测试这个特定的组件,默认情况下,这是 Jest 唯一不为我模拟的组件。我可以手动存根但不知何故不想工作。

我现在所做的是在 closeModal 中模拟 this.props.onClick 并检查它是否触发。

代码如下所示:

describe('QuestionForm', function() {
  var onClickFunc,
      form;

  beforeEach(function() {
    onClickFunc = jest.genMockFunction();

    form = TestUtils.renderIntoDocument(
      <QuestionForm onClick={onClickFunc} />
    );
  });

  it('should call closeModal when the icon is clicked', function() {
    var closeIcon = TestUtils.findRenderedDOMComponentWithClass(form, 'close-icon');

    TestUtils.Simulate.click(closeIcon);

    expect(onClickFunc).toBeCalled();
  });

});

我认为这充分测试了 closeModal 的行为是否符合预期。