测试 React 模态组件
Testing a React Modal component
很抱歉,我一直在尝试通过单击按钮来测试关闭我的 React Modal。模态非常简单,我已经尝试了我能想到或找到的所有方法,但我仍然无法查询它的子级。
模态组件:
var React = require('react');
var Modal = require('react-bootstrap').Modal;
var Button = require('react-bootstrap').Button;
var MyModal = React.createClass({
...
render: function() {
return (
<Modal className="my-modal-class" show={this.props.show}>
<Modal.Header>
<Modal.Title>My Modal</Modal.Title>
</Modal.Header>
<Modal.Body>
Hello, World!
</Modal.Body>
<Modal.Footer>
<Button onClick={this.props.onHide}>Close</Button>
</Modal.Footer>
</Modal>
);
}
});
我的目标是测试单击该"关闭"按钮时是否触发onHide()
函数。
我的测试文件:
describe('MyModal.jsx', function() {
it('tests the Close Button', function() {
var spy = sinon.spy();
var MyModalComponent = TestUtils.renderIntoDocument(
<MyModal show onHide={spy}/>
);
// This passes
TestUtils.findRenderedComponentWithType(MyModalComponent, MyModal);
// This fails
var CloseButton = TestUtils.findRenderedDOMComponentWithTag(MyModalComponent, 'button');
// Never gets here
TestUtils.Simulate.click(CloseButton);
expect(spy.calledOnce).to.be.true;
});
});
无论我尝试什么,我似乎都找不到关闭按钮。
我使用 React Base Fiddle (JSX) 编写了一个 jsFiddle 来找出测试中发生了什么(我创建了自己的"间谍",在调用时只是记录到控制台)。
我发现你找不到你的按钮的原因是因为它不存在你期望它的地方。
Bootstrap 模态组件 (<Modal/>
) 实际上包含在 React-Overlays 模态组件中(在代码中称为 BaseModal
,它来自这里)。这反过来又渲染了一个名为 Portal
的组件,其渲染方法仅返回 null
。您尝试在其上查找渲染组件的正是此null
值。
由于模态不是以传统的 React 方式渲染的,React 无法看到模态以便使用 TestUtils
。一个完全独立的<div/>
子节点放置在document
体中,这个新<div/>
用于构建模态。
因此,为了允许您使用 React 的TestUtils
模拟点击(按钮上的点击处理程序仍然绑定到按钮的点击事件),您可以使用标准 JS 方法来搜索 DOM。按如下方式设置测试:
describe('MyModal.jsx', function() {
it('tests the Close Button', function() {
var spy = sinon.spy();
var MyModalComponent = TestUtils.renderIntoDocument(
<MyModal show onHide={spy}/>
);
// This passes
TestUtils.findRenderedComponentWithType(MyModalComponent, MyModal);
// This will get the actual DOM node of the button
var closeButton = document.body.getElementsByClassName("my-modal-class")[0].getElementsByClassName("btn btn-default")[0];
// Will now get here
TestUtils.Simulate.click(CloseButton);
expect(spy.calledOnce).to.be.true;
});
});
该函数getElementsByClassName
返回具有该类的元素集合,因此您必须从每个集合中获取第一个(在您的测试用例中,也是唯一的一个)。
您的测试现在应该通过 ^_^
这是我最终采用的解决方案。它以 React 渲染模态的方式存根,只渲染一个<div>
。
test-utils.js
:
var sinon = require('sinon');
var React = require('react');
var Modal = require('react-bootstrap').Modal;
module.exports = {
stubModal: function() {
var createElement = React.createElement;
modalStub = sinon.stub(React, 'createElement', function(elem) {
return elem === Modal ?
React.DOM.div.apply(this, [].slice.call(arguments, 1)) :
createElement.apply(this, arguments);
});
return modalStub;
},
stubModalRestore: function() {
if (modalStub) {
modalStub.restore();
modalStub = undefined;
} else {
console.error('Cannot restore nonexistent modalStub');
}
}
};
modal-test.jsx
var testUtils = require('./test-utils');
describe('test a Modal!', function() {
before(testUtils.stubModal);
after(testUtils.stubModalRestore);
it('renders stuff', function() {
var MyModalComponent = TestUtils.renderIntoDocument(
<MyModal show/>
);
// Do more stuff you normally expect you can do
});
});
- 我想使用模态通过php文件发送邮件,并且我希望在提交关闭后关闭pop
- 打开一个模态并将其链接到AngularJS中的指令
- SemanticUI模态not onDeny/onApprove事件未激发
- 有没有比在app.js上绑定模块名称更好的方法来动态加载视图模型和视图以显示模态
- 如何通过所选索引(AngularJS)在模态弹出窗口中显示数据
- 包含数据库中相关信息的开放模态
- bootstrap消除模态并显示另一个模态
- 模态提示-如何重写此代码
- 模态框无法正常工作
- Twitter Bootstrap v3.0.0 未显示模态组件
- 如何使用 Reactjs 用组件的状态填充模态表单
- 测试 React 模态组件
- 反应/reux + 引导,使组件的模态显示唯一
- ngClick on Bootstrap's模态组件
- 为什么Angular UI引导使用提供程序来处理模态和工具提示中的逻辑,而不在其他组件中
- 从组件打开模态
- ReactJS:在模态中动态加载组件的最佳方式
- React用class查找所有组件,从外部更新组件状态或道具.模态叠加
- React-Redux与Bootstrap——模态组件
- 语义UI模态组件onClose with React