如何使用React Hooks测试hoc statefull组件?

时间:2019-05-13 20:31:40

标签: reactjs jestjs enzyme react-hooks

我有一个Layout hoc组件,我想保证状态更改。 这是我的布局组件:

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()的null,但这在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 个答案:

答案 0 :(得分:1)

请勿尝试通过变通办法来初始化状态。通过组件的公共界面与组件进行交互-我是说道具。

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()上进行操作或使用酶的setState()时,会将测试绑定到组件的内部,并且测试变得脆弱,没有优势。