4

findRenderedComponentWithTypeコンポーネントを使用しfindRenderedComponentWithTypeて見つけるために、いくつかの単体テストを実行しようとしています。しかし、私は少し問題を抱えています。

レンダリングされた浅いコンポーネントが<Layout />あり、その中に<UserMenu />.

var Layout = React.createClass({
    render: function(){
        console.log(this.props);
        return (
            <div id="data-trader">
                <header className="header">
                    <UserMenu user={this.props.user} />
                </header>
                <SideMenu user={this.props.user}/>
            </div>
        );
    }
});

module.exports = Layout;

テストファイル内で、これを試しました:

describe('Layout', function() {
    beforeEach(function(){
        fakeDOM = TestUtils.createRenderer();
        it('should exist as a component', function(done) {
            expect(<Layout/>).to.exist;
            done();
        });
        fakeDOM.render(<Layout />);
        renderedFakeDOMOutput = fakeDOM.getRenderOutput();
    });
    it('should have login button when props.user is undefined', function(done) {
        renderedFakeDOMOutput.props.user = undefined;
        let UserMenuComponent = TestUtils.scryRenderedComponentsWithType(renderedFakeDOMOutput, UserMenu);
        done();
    });
});

ただし、scryRenderedComponentsWithTypeタイプfindRenderedComponentWithTypeのコンポーネントは何も見つかりませんUserMenu

exportsまた、コンポーネントで別のファイルを作成しようとしましたUserMenuが、同じ出力または 0 が見つかりました (配列の長さ 0) またはコンポーネントが見つからない場合のエラー ( Error: Did not find exactly one match for componentType:function UserMenu()) を取得します。

4

1 に答える 1

1

あなたが尋ねている質問に対する直接的な解決策ではないことは知っていますが、浅いレンダリングを試したとき、あなたと同じように苦労しました。React 自身のドキュメントでは、この機能を「いくつかの制限」のある初期リリースとして説明しています。

現在、浅いテストにはいくつかの制限があります。つまり、参照をサポートしていません。私たちはこの機能を早期にリリースしており、どのように進化すべきかについて React コミュニティからのフィードバックをお待ちしております。

私は頭を壁にぶつけるのにうんざりし、他の場所で見つけたより簡単な解決策を採用しました。

http://substantial.com/blog/2014/11/11/test-driven-react-how-to-manually-mock-components/

リンクがうまくいかない場合: 基本的に、Rewireを使用して、サブコンポーネントをテストでインラインで作成したものと交換するように指示されています。これがまさに私がしていることです:

rewire-module.js (ブログ投稿からコピー)

module.exports = function rewireModule(rewiredModule, varValues) {
    var rewiredReverts = [];

    beforeEach(function () {
        var key, value, revert;
        for (key in varValues) {
            if (varValues.hasOwnProperty(key)) {
                value = varValues[key];
                revert = rewiredModule.__set__(key, value);
                rewiredReverts.push(revert);
            }
        }
    });

    afterEach(function () {
        rewiredReverts.forEach(function (revert) {
            revert();
        });
    });

    return rewiredModule;
};

MyList.jsx (スニペット)

<div>
    { items.map(item => <MyListItem key={item.id} item={item}/>) }
</div>

MyList-test.jsx (スニペット)

let rewireModule = require('../utils/rewire-module');
let rewire = require('rewire');
let MyList = rewire('./MyList.jsx');

rewireModule(MyList, {
    MyListItem: React.createClass({
        propTypes: {
            item: React.PropTypes.object.isRequired
        },
        render: function () {
            return <div className="MyListItem"/>;
        }
    })
});

it('should render data', function () {
    // init
    MyStore.onLoadCompleted([
        {id: 1, name: 'Test 1'},
        {id: 2, name: 'Test 2'}
    ]);

    let listComponent = TestUtils.renderIntoDocument(<MyList/>);
    let listItems = TestUtils.scryRenderedDOMComponentsWithClass(listComponent, 'MyListItem');
    expect(listItems.length).to.equal(2);

    // cleanup
    React.unmountComponentAtNode(listComponent.getDOMNode());
});

お気づきかもしれませんが、私は基本的に「className」を要素識別子として使用して、後でそれらを見つけます。

特定のデータを持つ特定のサブコンポーネントを検索したい場合は、className に固有のものを作成することがあります。

rewireModule(MyList, {
    MyListItem: React.createClass({
        propTypes: {
            item: React.PropTypes.object.isRequired
        },
        render: function () {
            return <div className={'MyListItem_' + item.id}/>;
        }
    })
});

it('should render data', function () {
    // init
    MyStore.onLoadCompleted([
        {id: 1, name: 'Test 1'},
        {id: 2, name: 'Test 2'}
    ]);

    let listComponent = TestUtils.renderIntoDocument(<MyList/>);
    TestUtils.findRenderedDOMComponentWithClass(listComponent, 'MyListItem_1');
    TestUtils.findRenderedDOMComponentWithClass(listComponent, 'MyListItem_2');

    // cleanup
    React.unmountComponentAtNode(listComponent.getDOMNode());
});
于 2015-08-17T20:05:44.853 に答える