web-dev-qa-db-ja.com

React&Jest、状態の変化をテストし、別のコンポーネントをチェックする方法

React-テストユーティリティドキュメント

_this.state.error_がtrueの場合、Notificationコンポーネントを表示するLoginコンポーネントがあります。

これをテストするためのJestテストを書いています。

_import React from 'react'
import ReactTestUtils from 'react-dom/test-utils';
import { shallow } from 'enzyme'
import toJson from 'enzyme-to-json'
import Login from './Login'
import Notification from '../common/Notification'

describe('<Login /> component', () => {
    it('should render', () => {
        const loginComponent = shallow(<Login />);
        const tree = toJson(loginComponent);
        expect(tree).toMatchSnapshot();
    });

    it('should contains the words "Forgot Password"', () => {
        const loginComponent = shallow(<Login />);
        expect(loginComponent.contains('Forgot Password')).toBe(true);
    });

    // This test fails
    it('should render the Notification component if state.error is true', () => {
        const loginComponent = ReactTestUtils.renderIntoDocument(
            <Login />
        );

        const notificationComponent = ReactTestUtils.renderIntoDocument(
            <Notification />
        );

        loginComponent.setState({
            error: true
        }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));
    });
});
_

ただし、現在テストは失敗しており、理由はわかりません

enter image description here

私のコードの最後の部分で、私はこれを無駄に試しました

_loginComponent.setState({
        error: true
    }, expect(ReactTestUtils. isElement(notificationComponent)).toBe(true));
_

https://facebook.github.io/react/docs/test-utils.html

ログインコンポーネントのrender()

_render() {
    const usernameError = this.state.username.error;
    const error = this.state.error;
    const errorMsg = this.state.errorMsg;

    return (
        <div className="app-bg">
            { error &&
                <Notification message={ errorMsg } closeMsg={ this.closeMessage }/>
            }
            <section id="auth-section">
                <header>
                    <img src="static/imgs/logo.png"/>
                    <h1>tagline</h1>
                </header>
_

また、state.errorをtrueに設定した後、通知コンポーネントをテストするためにこのメソッドを試しました

_it('should render the Notification component if state.error is true', () => {
    const loginComponent = ReactTestUtils.renderIntoDocument(
        <Login />
    );

    const notificationComponent = ReactTestUtils.renderIntoDocument(
        <Notification />
    );

    // loginComponent.setState({
    //  error: true
    // }, expect(ReactTestUtils.isDOMComponent(notificationComponent)).toBe(true));

    const checkForNotification = () => {
        const login = shallow(<Login />);
        expect(login.find(Notification).length).toBe(1);
    };

    loginComponent.setState({
        error: true
    }, checkForNotification());
});
_

しかし、そのテストも失敗しました。

const login = mount(<Login />);も試しました


JestとReact Test Utilities?

19
Leon Gaban

理解した! React Test Utilities は必要ありませんでした

it('should render the Notification component if state.error is true', () => {
    const loginComponent = shallow(<Login />);
    loginComponent.setState({ error: true });
    expect(loginComponent.find(Notification).length).toBe(1);
});

これにより、Loginコンポーネントでエラーの状態がtrueに設定され、Loginコンポーネントには、Notificationコンポーネントが含まれます。

42
Leon Gaban

これはおそらく少しリファクタリングする必要があります。 Notificationコンポーネントはおそらくalwaysよりグローバルなコンポーネント(Page Wrapperやその他のコンテナなど)でレンダリングされる必要があり、おそらくnullをレンダリングする必要があります。グローバルレデューサー内にエラーがあります。おそらく、Loginコンポーネントは、通知に関する責任とビジネスロジックを維持すべきではありません。

2
Swivel