3

次を使用して、その子も利用するReactコンポーネントがありますthis.props.children

import classnames from 'classnames';
import React from 'react';

export default function Toolbar(props) {
    return <ul className="sulu-Toolbar">{props.children}</ul>;
}

Toolbar.Item = class extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            open : false
        };
    }

    static propTypes = {
        title: React.PropTypes.string,
        isChild: React.PropTypes.bool
    };

    static defaultProps = {
        title: '',
        isChild: false
    };

    render() {
        var classNames = classnames({
            'sulu-Toolbar-Item': !this.props.isChild,
            'sulu-Toolbar-Item-Dropdown-Item': this.props.isChild
        });

        return <li className={classNames} onClick={this.onClick}>
            {this.props.title} {this.props.children ? <span className="sulu-Toolbar-Item-Arrow"/> : ''}
            {!!this.props.children ? this.getChildren() : ''}
        </li>;
    }

    getChildren = () => {
        var children = null;

        if (!!this.state.open) {
            children = <ul className="sulu-Toolbar-Item-Dropdown">
                {
                    this.props.children.map((child) => {
                        return <Toolbar.Item {...child.props} key={child.key} isChild={true}/>;
                    })
                }
            </ul>;
        }

        return children;
    };

    onClick = () => {
        !!this.props.children ? this.toggleOpen() : this.props.onClick();
    };

    toggleOpen = () => {
        this.setState({open: !this.state.open});
    };
};

これはこれまでのところブラウザではうまく機能しますが、酵素を使用してテストしようとすると、奇妙なエラーが発生します。これはテストです:

import {mount, shallow} from 'enzyme';
import React from 'react';
import test from 'tape';

import Toolbar from '../src/toolbar';

import './setup.js';

test('Toolbar item should open and close', (t) => {
    const toolbarItem = mount(<Toolbar.Item><Toolbar.Item/></Toolbar.Item>);

    t.test('Toolbar item should open', (t) => {
        t.plan(1);
        toolbarItem.find('li').simulate('click');
        t.equals(toolbarItem.find('p').length, 1);
    });

    t.test('Toolbar item should close', (t) => {
        t.plan(1);
        toolbarItem.find('li').simulate('click');
        t.equals(toolbarItem.find('p').length, 0);
    });
});

test('Toolbar item should execute onclick handler', (t) => {
    t.plan(1);

    const toolbarItem = shallow(<Toolbar.Item onClick={() => {t.ok(true)}}/>);

    toolbarItem.find('li').simulate('click');
});

test ('Toolbar item should show title', (t) => {
    t.plan(1);

    const toolbarItem = shallow(<Toolbar.Item title="Test"/>);

    t.ok(toolbarItem.contains('Test'));
});

そのテストを実行しようとすると、次のエラー メッセージが表示されます。

> @ test /Users/daniel/Development/personal/react-playground
> tape -r ./test/babel-register-setup test/*-test.js

TAP version 13
# Toolbar item should open and close
# Toolbar item should open
/Users/daniel/Development/personal/react-playground/src/toolbar.js:54
                    _this.props.children.map(function (child) {
                                         ^

TypeError: _this.props.children.map is not a function
    at _class._this.getChildren (toolbar.js:45:41)
    at _class.render (toolbar.js:35:43)
    at ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:785:34)
    at ReactCompositeComponentMixin._renderValidatedComponent (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:811:32)
    at ReactCompositeComponentMixin._updateRenderedComponent (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:735:36)
    at ReactCompositeComponentMixin._performComponentUpdate (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:715:10)
    at ReactCompositeComponentMixin.updateComponent (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:634:12)
    at ReactCompositeComponentMixin.performUpdateIfNecessary (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactCompositeComponent.js:548:12)
    at Object.ReactReconciler.performUpdateIfNecessary (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactReconciler.js:165:22)
    at runBatchedUpdates (/Users/daniel/Development/personal/react-playground/node_modules/react/lib/ReactUpdates.js:151:21)

npm ERR! Darwin 15.4.0
npm ERR! argv "/usr/local/Cellar/node/6.3.1/bin/node" "/usr/local/bin/npm" "run" "test"
npm ERR! node v6.3.1
npm ERR! npm  v3.10.3
npm ERR! code ELIFECYCLE
npm ERR! @ test: `tape -r ./test/babel-register-setup test/*-test.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the @ test script 'tape -r ./test/babel-register-setup test/*-test.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the  package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     tape -r ./test/babel-register-setup test/*-test.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/daniel/Development/personal/react-playground/npm-debug.log

もちろん、私はそれを望んでいますが、mountとでそれをやろうとしました。しかし、両方の機能が期待どおりに機能しません。私はjsdomも使用しており、テストに含まれている次のスクリプトを使用しています。shallowshallowmountsetup.js

import jsdom from 'jsdom';

if (typeof document === 'undefined') {
    global.document = jsdom.jsdom('<html><body></body></html>');
    global.window = document.defaultView;
    global.navigator = window.navigator;
}

そして、私が間違っていることを考えていますか?

アップデート:

コードにa を追加するconsole.log(this.props.children)と、テストで次の構造が得られます。

{ '$$typeof': Symbol(react.element),
  type:
   { [Function: _class]
     propTypes: { title: [Object], isChild: [Object] },
     defaultProps: { title: '', isChild: false } },
  key: null,
  ref: null,
  props: { title: '', isChild: false },
  _owner: null,
  _store: {} }
4

0 に答える 0