2016-01-29 12 views
5

申し訳ありませんが、ボタンをクリックしてReact Modalをテストしようとすると、最も厳しい時間がかかりました。モーダルはできるだけシンプルであり、私は考えることができる、または見つけることができるすべてを試しましたが、私はまだその子を照会できません。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; 
    }); 
}); 

どんなに私がしようとするもの、私は閉じるボタンを見つけるように見えることはできません。

+0

あなたは冗談を使用していますか?私は冗談を一度も使用していませんが、私はそれが依存するコンポーネントを自動で模倣していると思います。それは問題になることができますか? –

+0

@AbhishekJain私はMochaを使用しています – user1778856

+0

は '

答えて

6

私はReact Base Fiddle (JSX)を使ってjsFiddleと書いて、あなたのテストで何が起こっていたのかを知ることができました。(私は自分の「スパイ」を作成しました。

あなたのボタンを見つけることができない理由は、あなたが期待していた場所に存在しないためです。

Bootstrap Modal Component<Modal/>)は、実際に(hereであるコードにBaseModalと呼ばれる)React-Overlaysモーダル成分内に含まれます。これにより、Portalと呼ばれるコンポーネントがレンダリングされ、render methodは単にnullを返します。レンダリングされたコンポーネントを検索しようとしているのはnullです。

従来のリアクション方法ではないモーダルのため、リアクトは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機能(およびテストケースでは、あなたの唯一の1)から各コレクションを。

テストに合格する必要があります。^ _^

+0

'findRenderedDOMComponentWithTag'は1の代わりに0を見つけるため失敗します:( – user1778856

+0

ああ、私はそれを持っていると思っていました!何か新しいものが見つかったら私の答えを編集します) –

+0

私は新しい解決策で自分の答えを更新しました。あなたに何か問題があるかどうか教えてください。) –

1

これは私が解決した解決策です。 ReactがModalをレンダリングする方法をスタブし、代わりに<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 
    }); 
}); 
関連する問題