我正在尝试学习如何使用React Shallow Rendering TestUtil并让测试通过,直到我向两者添加了onClick
事件处理程序;似乎我在Accordion.toggle
Accordion.test.js
与this.toggle
Accordian.js
中使用的Accordian.test.js
函数必定存在一些差异......但我无法弄明白
如何才能让npm install
中的两个突出显示的测试通过?
npm run dev
npm run test:watch
- 当您点击“Lorem Ipsum”Option Explicit
Dim clsobject As clsComboBox
Private Sub CommandButton1_Click()
Dim ctlcombobox As ComboBox
Set ctlcombobox = Me.Controls.Add("Forms.ComboBox.1", "ComboBox1", True)
Set clsobject = New clsComboBox
Set clsobject.cmboControl = ctlcombobox
With ctlcombobox
.Top = 100
.Left = 5
.Width = 200
.Height = 25
.Visible = True
.List = Array("1", "2")
End With
End Sub
- 看到测试失败答案 0 :(得分:9)
有许多问题阻止您的测试通过。
查看测试"默认情况下应该处于非活动状态":
Accordion.toggle
是Accordion
类的属性,代码中的this.toggle
是Accordion
类实例的属性 - 所以在这种情况下你要比较两件不同的东西。要访问'实例'在测试中,您可以将Accordion.toggle
替换为Accordion.prototype.toggle
。如果它不是你的构造函数中的this.toggle = this.toggle.bind(this);
,那将会有效。这引出了我们的第二点。
在函数上调用.bind()时,它会在运行时创建一个新函数 - 因此您无法将其与原始Accordion.prototype.toggle
进行比较。解决这个问题的唯一方法就是拉开"绑定"函数取决于渲染的结果:
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>
]);
至于你的第二次失败测试&#34;点击后应该变为活动状态&#34;:
您尝试调用不存在的result.props.onClick()
。您打算致电result.props.children[0].props.onClick();
React中存在一个错误,需要全局&#34;文档&#34;在使用浅渲染调用setState时要声明的变量 - 如何在每种情况下解决这个问题超出了这个问题的范围,但是快速解决问题的方法是在调用之前添加global.document = {};
onClick方法。换句话说,你的原始测试有:
result.props.onClick();
现在应该说:
global.document = {};
result.props.children[0].props.onClick();
参见&#34;修复破碎的setState()&#34; on this page和this react issue。
答案 1 :(得分:3)
Marcin Grzywaczewski写了一篇很棒的article,其中包含一个测试点击处理程序的解决方法,该处理程序适用于浅层渲染。
给定一个带有onClick
prop的嵌套元素和一个绑定到组件的上下文的处理程序:
render() {
return (
<div>
<a className="link" href="#" onClick={this.handleClick}>
{this.state.linkText}
</a>
<div>extra child to make props.children an array</div>
</div>
);
}
handleClick(e) {
e.preventDefault();
this.setState({ linkText: 'clicked' });
}
您可以在事件对象中手动调用onClick
prop的函数值:
it('updates link text on click', () => {
let tree, link, linkText;
const renderer = TestUtils.createRenderer();
renderer.render(<MyComponent />);
tree = renderer.getRenderOutput();
link = tree.props.children[0];
linkText = link.props.children;
// initial state set in constructor
expect(linkText).to.equal('Click Me');
// manually invoke onClick handler via props
link.props.onClick({ preventDefault: () => {} });
tree = renderer.getRenderOutput();
link = tree.props.children[0];
linkText = link.props.children;
expect(linkText).to.equal('Clicked');
});
答案 2 :(得分:1)
要测试onClick
等用户事件,您必须使用TestUtils.Simulate.click
。 Sadly:
现在不可能将ReactTestUtils.Simulate与Shallow渲染一起使用,我认为要遵循的问题应该是:https://github.com/facebook/react/issues/1445
答案 3 :(得分:0)
我已经成功测试了我的无状态组件中的点击。方法如下:
我的组件:
import './ButtonIcon.scss';
import React from 'react';
import classnames from 'classnames';
const ButtonIcon = props => {
const {icon, onClick, color, text, showText} = props,
buttonIconContainerClass = classnames('button-icon-container', {
active: showText
});
return (
<div
className={buttonIconContainerClass}
onClick={onClick}
style={{borderColor: color}}>
<div className={`icon-container ${icon}`}></div>
<div
className="text-container"
style={{display: showText ? '' : 'none'}}>{text}</div>
</div>
);
}
ButtonIcon.propTypes = {
icon: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired,
color: React.PropTypes.string,
text: React.PropTypes.string,
showText: React.PropTypes.bool
}
export default ButtonIcon;
我的测试:
it('should call onClick prop when clicked', () => {
const iconMock = 'test',
clickSpy = jasmine.createSpy(),
wrapper = ReactTestUtils.renderIntoDocument(<div><ButtonIcon icon={iconMock} onClick={clickSpy} /></div>);
const component = findDOMNode(wrapper).children[0];
ReactTestUtils.Simulate.click(component);
expect(clickSpy).toHaveBeenCalled();
expect(component).toBeDefined();
});
重要的是包装组件:
<div><ButtonIcon icon={iconMock} onClick={clickSpy} /></div>
希望有所帮助!