Как проверить компонент hoc statefull с помощью React Hooks? - PullRequest
0 голосов
/ 13 мая 2019

У меня есть компонент Layout hoc, и я хочу гарантировать изменения состояния. Вот мой компонент Layout:

import React, { useState } from 'react'

import styles from './Layout.module.css'
import Toolbar from '../../components/UI/Navigation/Toolbar/Toolbar'
import SideDrawer from '../../components/UI/Navigation/SideDrawer/SideDrawer'

const Layout = (props) => {

    const [sideDrawerIsVisible, setSideDrawerIsVisible] = useState(false)

    const sideDrawerClosedHandler = () => {
        setSideDrawerIsVisible(false)
    }

    const slideDrawerToggleHandler = () => {
        setSideDrawerIsVisible((prevState) => !prevState)
    }

    return (
        <>
            <Toolbar
                height="2em"
                drawerToggleClicked={slideDrawerToggleHandler} />
            <SideDrawer
                open={sideDrawerIsVisible}
                closed={sideDrawerClosedHandler} />
            <main className={styles.Content}>
                {props.children}
            </main>
        </>
    );
}

export default Layout

Решение, которое я нашел, получает экземпляр и использует useState().

Мне нужен экземпляр, чтобы установить состояние и проверить его после действия щелчка. Тест под рукой - should update state when drawer toggle clicked, но в соответствии с документацией Enzyme для компонентов без сохранения состояния мы получаем нулевое значение до instance(), но это изменилось в React Hooks. Есть лучший подход для проверки этой ситуации?

import React from 'react';

import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

import Layout from './Layout';
import Toolbar from '../../components/UI/Navigation/Toolbar/Toolbar';

configure({ adapter: new Adapter() });

describe('<Layout />', () => {
    let wrapper;

    beforeEach(() => {
        wrapper = shallow(<Layout>children...</Layout>);
    });

    it('should update state when drawer toggle clicked', () => {
        const toolbar = wrapper.find(Toolbar);
        wrapper.instance().setSideDrawerIsVisible(true);
        toolbar.props().drawerToggleClicked();
        expect(wrapper.sideDrawerIsVisible).toEqual(false);
    });
});

1 Ответ

1 голос
/ 14 мая 2019

Только не пытайтесь инициировать состояние обходными путями.Взаимодействуйте с компонентом через его открытый интерфейс - я имею в виду реквизит.

it('displays drawer after toolbar is clicked', () => {
    const toolbar = wrapper.find(Toolbar);
    toolbar.props().drawerToggleClicked();
    expect(wrapper.find(SideDrawer).props().open).toEqual(true);
});

it('hides drawer after toolbar is clicked for second time', () => {
    const toolbar = wrapper.find(Toolbar);
    toolbar.props().drawerToggleClicked();
    toolbar.props().drawerToggleClicked();
    expect(wrapper.find(SideDrawer).props().open).toEqual(false);
});

it('hides drawer initially shown after closing it from inside', () => {
    const toolbar = wrapper.find(Toolbar);
    toolbar.props().drawerToggleClicked(); // to display drawer
    const sideDrawer = wrapper.find(SideDrawer);
    sideDrawer.props().closed();
    expect(sideDrawer.props().open).toEqual(false);
});

, когда вы работаете с instance() напрямую или используете Enzyme setState(), вы ограничиваете свои тесты внутренними компонентами, и тесты становятся хрупкими без каких-либо преимуществ..

...