使用Jest和React Hooks库测试React钩子状态

时间:2020-01-21 21:30:07

标签: reactjs testing react-hooks react-hooks-testing-library

然后,我的nav组件将在边栏中切换状态以及打开和关闭菜单,然后尝试在代码覆盖率中获得此权限。当我登录测试时,状态始终显示为未定义。不知道如何在这里解决这个问题。

Component.js:

const Navigation = (props) => {
  const {
    classes,
    ...navProps
  } = props;

  const [anchorEl, setanchorEl] = useState(null);
  const [sidebarOpen, setsidebarOpen] = useState(false);

  const toggleSidebar = () => {
    setsidebarOpen(!sidebarOpen);
  };

  const toggleMenuClose = () => {
    setanchorEl(null);
  };

  const toggleMenuOpen = (event) => {
    setanchorEl(event.currentTarget);
  };

  return (
    <Fragment>
     <Button
          onClick={toggleMenuOpen}
        />
      <SideMenu
        toggleSidebar={toggleSidebar}
      >
       <Menu
          onClose={toggleMenuClose}
        >
      </SideMenu>
    </Fragment>
  );
};

export default Navigation;

Test.js:

import { renderHook, act } from '@testing-library/react-hooks';

// Components
import Navigation from './navigation';

test('sidebar should be closed by default', () => {
    const newProps = {
        valid: true,
        classes: {}
    };

    const { result } = renderHook(() => Navigation({ ...newProps }));
    expect(result.current.sidebarOpen).toBeFalsy();
});

1 个答案:

答案 0 :(得分:4)

此处react-hooks-testing-library的作者。

react-hooks-testing-library不是用于测试组件并询问内部挂钩状态以声明其值,而是用于测试自定义反应挂钩并与挂钩结果进行交互以确保其行为符合预期。例如,如果您要提取一个类似于以下内容的useMenuToggle钩子:

export function useMenuToggle() {
  const [anchorEl, setanchorEl] = useState(null);
  const [sidebarOpen, setsidebarOpen] = useState(false);

  const toggleSidebar = () => {
    setsidebarOpen(!sidebarOpen);
  };

  const toggleMenuClose = () => {
    setanchorEl(null);
  };

  const toggleMenuOpen = (event) => {
    setanchorEl(event.currentTarget);
  };

  return {
    sidebarOpen,
    toggleSidebar,
    toggleMenuClose,
    toggleMenuOpen
  }
}

然后您可以使用renderHook对其进行测试:

import { renderHook, act } from '@testing-library/react-hooks';

// Hooks
import { useMenuToggle } from './navigation';

test('sidebar should be closed by default', () => {
    const newProps = {
        valid: true,
        classes: {}
    };

    const { result } = renderHook(() => useMenuToggle());
    expect(result.current.sidebarOpen).toBeFalsy();

    act(() => {
        result.current.toggleSidebar()
    })

    expect(result.current.sidebarOpen).toBeTruthy();
});

但是,通常,当一个钩子仅由单个组件和/或在单个上下文中使用时,我们建议您仅测试该组件并允许通过该钩子进行测试。

要测试您的Navigation组件,您应该查看react-testing-library

import React from 'react';
import { render } from '@testing-library/react';

// Components
import Navigation from './navigation';

test('sidebar should be closed by default', () => {
    const newProps = {
        valid: true,
        classes: {}
    };

    const { getByText } = render(<Navigation {...newProps} />);
    
    // the rest of the test
});