Javascript 测试反应模态组件
很抱歉,我一直在尝试通过单击按钮来关闭我的反应模式,这是我最困难的一次尝试。模态尽可能简单,我已经尝试了我能想到或找到的一切,但我仍然无法查询它的子对象 模态分量:Javascript 测试反应模态组件,javascript,unit-testing,reactjs,bootstrap-modal,react-jsx,Javascript,Unit Testing,Reactjs,Bootstrap Modal,React Jsx,很抱歉,我一直在尝试通过单击按钮来关闭我的反应模式,这是我最困难的一次尝试。模态尽可能简单,我已经尝试了我能想到或找到的一切,但我仍然无法查询它的子对象 模态分量: var React = require('react'); var Modal = require('react-bootstrap').Modal; var Button = require('react-bootstrap').Button; var MyModal = React.createClass({ ...
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>
);
}
});
无论我尝试什么,我似乎都找不到关闭按钮。我使用编写了一个脚本,以了解测试中发生了什么(我创建了自己的“spy”,调用时只需登录到控制台)
我发现你找不到你的按钮的原因是因为它不存在于你期望的地方
(
)实际上包含在模态组件中(在代码中称为BaseModal
,它来自)。这反过来会呈现一个名为Portal
的组件,该组件只返回null
。正是该null
值是您试图在其上查找渲染组件的值
由于模态没有以传统的React方式呈现,React无法看到模态以便使用TestUtils
on。一个完全独立的
子节点放置在文档
正文中,这个新的
用于构建模型
因此,为了允许您使用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;
});
});
description('MyModal.jsx',function(){
它('测试关闭按钮',函数(){
var spy=sinon.spy();
var MyModalComponent=TestUtils.renderIntoDocument(
);
//这过去了
TestUtils.findRenderedComponentWithType(MyModalComponent,MyModal);
//这将获得按钮的实际DOM节点
var closeButton=document.body.getElementsByClassName(“我的模态类”)[0].getElementsByClassName(“btn btn默认值”)[0];
//我现在就到这里
TestUtils.Simulate.click(关闭按钮);
期望(spy.calledOnce).to.be.true;
});
});
函数getElementsByClassName
返回该类的元素集合,因此您必须从每个集合中获取第一个(在您的测试用例中是唯一的一个)
您的测试现在应该通过了^ ^这就是我最终采用的解决方案。它将React渲染模态的方式改为只渲染
测试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');
}
}
};
模态测试.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
});
});
var testUtils=require('./testUtils');
描述('testa Modal!',function(){
之前(testUtils.stubModal);
之后(testUtils.stummodalrestore);
它('renders stuff',function(){
var MyModalComponent=TestUtils.renderIntoDocument(
);
//做更多你通常期望你能做的事情
});
});
你在开玩笑吗?我从未使用过玩笑,但我认为它会自动模拟依赖组件。这可能是问题所在吗?@AbhishekJain我正在使用Mochais
一个用户定义的类,或者您正在尝试执行
?@HenrikAndersson我应该澄清这是React引导的一部分,FindRenderedomComponentWithTag
的可能重复项失败,因为它找到0而不是1:(哦,不!我还以为我找到了呢!我暂时把这个放在这里,但我会继续努力。当我找到新的内容时,我会编辑我的答案=)我已经用新的解决方案更新了我的答案。如果你有任何问题,请告诉我=)我遇到了一个几乎相同的问题,这个解决方案对我有效。它应该被标记为正确的IMO。这是有效的!我花了两个小时试图找出我的测试出了什么问题。谢谢你的解释!
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
});
});