React Testing:React Shallow Rendering单元测试中的事件处理程序 [英] React Testing: Event handlers in React Shallow Rendering unit tests
问题描述
我正在努力学习如何使用React Shallow渲染TestUtil并测试通过,直到我向两者添加了 onClick
事件处理程序;似乎与我在 Accordion.test.js
Accordion.toggle 函数有一些区别。 > vs this.toggle
in Accordian.js
...但我无法理解。
I am trying to learn how to use the React Shallow Rendering TestUtil and had the tests passing until I added an onClick
event handler to both; It seems that there must be some difference with the Accordion.toggle
function I am trying to use in Accordion.test.js
vs this.toggle
in Accordian.js
...but I can't figure it out.
如何在 Accordian.test.js中获得两个突出显示的测试
要通过?
- 克隆< a href =https://github.com/trevordmiller/shallow-rendering-testing-playground =noreferrer> https://github.com/trevordmiller/shallow-rendering-testing-playground
-
npm install
-
npm run dev
- 当你点击Lorem Ipsum时看到该组件正常工作 -
npm run test:watch
- 看看测试失败了
- Clone https://github.com/trevordmiller/shallow-rendering-testing-playground
npm install
npm run dev
- see that component is working when you click "Lorem Ipsum"npm run test:watch
- see that tests are failing
推荐答案
有许多问题阻止您的测试通过。
There are a number of issues preventing your tests from passing.
看看测试应该是默认情况下不活动:
Looking at the test "should be inactive by default":
-
您的测试中的Accordion.toggle
是Accordion
类的属性,以及代码中this.toggle
的属性是<$的实例的属性c $ c> Accordion class - 所以在这种情况下你要比较两个不同的东西。要在测试中访问instance方法,您可以使用Accordion.prototype.toggle
替换Accordion.toggle
。如果你的构造函数不是this.toggle = this.toggle.bind(this);
,那将会有效。这引出了我们的第二点。
Accordion.toggle
in your test is a property of theAccordion
class, andthis.toggle
in your code is a property of a instance of theAccordion
class - so in this case you are comparing two different things. To access the 'instance' method in your test you could replaceAccordion.toggle
withAccordion.prototype.toggle
. Which would work if it were not forthis.toggle = this.toggle.bind(this);
in your constructor. Which leads us to the second point.
当你在函数上调用.bind()时它会在运行时创建一个新函数 - 所以你无法比较它到原来的 Accordion.prototype.toggle
。解决这个问题的唯一方法是从渲染结果中拉出绑定函数:
When you call .bind() on a function it creates a new function at runtime - so you can't compare it to the original Accordion.prototype.toggle
. The only way to work around this is to pull the "bound" function out of the result from render:
let toggle = result.props.children[0].props.onClick;
assert.deepEqual(result.props.children, [
<a onClick={toggle}>This is a summary</a>,
<p style={{display: 'none'}}>This is some details</p>
]);
至于你的第二次失败测试应该成为单击时激活:
As for your second failing test "should become active when clicked":
-
您尝试调用
result.props.onClick()
哪个不存在。你的意思是打电话给result.props.children [0] .props.onClick();
You try calling
result.props.onClick()
which does not exist. You meant to callresult.props.children[0].props.onClick();
React中存在一个错误,它需要在使用浅渲染调用setState时声明全局文档变量 - 如何在每种情况下解决这个问题都超出了这个问题的范围,但是快速解决方法让你的测试通过是在调用onClick方法之前添加 global.document = {};
。换句话说,你的原始测试有:
There is a bug in React that requires a global "document" variable to be declared when calling setState with shallow rendering - how to work around this in every circumstance is beyond the scope of this question, but a quick work around to get your tests passing is to add global.document = {};
right before you call the onClick method. In other words where your original test had:
result.props.onClick();
现在应该说:
global.document = {};
result.props.children[0].props.onClick();
See the section "Fixing Broken setState()" on this page and this react issue.
这篇关于React Testing:React Shallow Rendering单元测试中的事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!