如何在ReactJS中使用适当的,可测试的事件处理程序来创建可重用的组件

时间:2015-02-02 22:11:52

标签: javascript coffeescript reactjs

假设您想要一个“反应”组件,它会引发一个自定义事件",就像这个复选框一样(在CoffeeScript中):

CustomCheckbox = React.createClass
  displayName: "Checkbox"

  getDefaultProps: -> 
    onCheckedChange: () ->

  render: -> 
    <div className="parent">
        <div className={className} onClick={@onClick}></div>
    </div>

  onClick: -> 
    @props.onCheckedChange(); // call the given event handler directly

现在我想编写一个使用该组件并模拟事件的测试:

describe 'SomeOtherComponentThatUsesACheckbox', ->
  it "some other component that uses a checkbox handles onCheckedChanged", ->
    isChecked = false
    handler = () -> isChecked = true

    checkbox = ReactTestUtils.renderIntoDocument(
      <CustomCheckbox onCheckedChange={handler} />
    );

    ReactTestUtils.Simulate.checkedChange(checkbox)

    isChecked.should.be.equal true

这不会奏效。模拟上没有checkedChange,如果有,它只会发出一个没人监听的事件,因为onCheckedChange处理程序没有连接到任何东西,只是直接调用。也许它不应该工作。

但问题是:

如何编写CustomCheckbox以便以相同的方式引发和订阅事件React自己的组件,例如<div><a>

我可以编写CustomCheckbox,以便我可以使用ReactTestUtils来模拟checkedChanged事件吗?

如果没有,那么在不知道可重用组件的内部结构的情况下,如何使用其他可重用组件进行测试?

更新

我已经更新了一点问题,以便更具体地解决问题。我为组件生成的html增加了一点复杂性。问题更准确:如何在不知道复杂组件内部的情况下模拟事件?

1 个答案:

答案 0 :(得分:2)

您没有触发自定义事件。您的活动是点击事件,您的处理程序是onClick处理程序,因此使用simulate.click应该有效。

如果要确保在单击事件发生时调用checkedChange处理程序,则应在测试中传递模拟处理程序并监视它。我不知道coffeescript中的语法是什么,但是像这样:

describe 'SomeOtherComponentThatUsesACheckbox',
  -> it "some other component that uses a checkbox handles onCheckedChanged", -> isChecked = false
  handler = () -> jasmine.createSpy()
      checkbox = ReactTestUtils.renderIntoDocument(
        <CustomCheckbox onCheckedChange={handler} />
      );
  ReactTestUtils.Simulate.click(checkbox) 
  expect(handler).toHaveBeenCalled();

您可以对自定义复选框组件进行单元测试,以查看isChecked实际上是否也发生了变化,但是它使用的是onClick事件,而不是其他事件。

此外,您可以将处理程序作为onClick处理程序传递给props,然后从外部明显看出click事件会触发它。