在Jest中调用React的this.props.onClick(this)时我究竟要测试什么?

时间:2015-05-04 16:13:05

标签: javascript reactjs jestjs

我一直在为我的所有事件(当然还有其他所有事件)编写测试但是我对如何测试这个问题感到茫然。在子组件上调用了.props.onClick(this)。

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

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

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

并且父母正在这样听:

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

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

我知道如何测试父母的点击事件,我知道如何在测试中调用孩子的按钮点击事件,但我不确定我应该准确测试什么。

如果我使用了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未被模拟但仍然运行(此时我有一个控制台日志)。我整个下午一直在这里,但一直都没能弄清楚。任何帮助将非常感激。

3 个答案:

答案 0 :(得分:7)

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

我现在所做的就是在closeModal中模拟this.props.onClick,然后检查它是否会触发。

以下是代码中的外观:

if (list == 1) {
    option_to_hide2 = document.getElementById(team_selected + 2);
    option_to_hide2.style.display = 'none';
}

我认为充分测试closeModal的行为与预期一致。

答案 1 :(得分:1)

如果您想检查该功能是否已被调用,您想要使用jest的toBeCalled功能(或toBeCalledWith)。假设您已完成一些设置来实例化组件,renderIntoDocument并模拟点击(如果没有,则结帐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 prop传递给Question,并检查它是否被调用。

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

答案 2 :(得分:0)

您可以使用异步测试。您必须在done()处理程序中调用onClick。如果一切正常,处理程序将调用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);
});