[英]Testing a React Modal component
對不起,我一直在努力嘗試通過點擊按鈕來關閉我的React Modal。 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
的組件,其render方法只返回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
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.