假设您想要一个“引发自定义事件”的 React 组件,例如这个复选框(在 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 添加了一些复杂性。问题更确切地说:如何在不知道复杂组件内部结构的情况下模拟事件?
最佳答案
您没有触发自定义事件。您的事件是点击事件,您的处理程序是 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
事件,而不是另一个事件。
此外,您可以将处理程序作为 props 中的 onClick
处理程序传递,然后从外部可以明显看出点击事件触发了它。
关于javascript - 如何在 ReactJS 中使用适当的、可测试的事件处理程序制作可重用的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28287763/