如何使用酶和Jest测试自定义钩子事件

时间:2020-08-15 19:15:38

标签: reactjs unit-testing jestjs enzyme

我创建了一个组件,该组件显示带有子组件的模式视图。单击该按钮即可显示该视图。

import React, { useRef, useState } from 'react';
import PropTypes from 'prop-types';

import { BsThreeDots } from 'react-icons/bs';
import useVisibleHandler from '~/helpers/hooks/useVisibleHandler';

import {
  Container,
  ButtonWrapper,
  ActionList,
  ActionContainer,
} from './styles';

export default function ActionsMenu({ children }) {
  const actionsMenuRef = useRef();
  const [visible, setVisible] = useState(false);

  useVisibleHandler(actionsMenuRef, () => {
    if (visible) {
      setVisible(false);
    }
  });

  function handleToggleVisible() {
    setVisible(!visible);
  }

  return (
    <Container data-testid="actions-menu-container" ref={actionsMenuRef}>
      <ButtonWrapper data-testid="button-wrapper" onClick={handleToggleVisible}>
        <BsThreeDots size={22} color="#b2b2b2" />
      </ButtonWrapper>

      <ActionList data-testid="action-list" visible={visible}>
        <ActionContainer>{children}</ActionContainer>
      </ActionList>
    </Container>
  );
}

ActionsMenu.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.node),
    PropTypes.node,
  ]).isRequired,
};

我已通过ref将事件监听器添加到此组件中,以供鼠标离开。

import { useEffect } from 'react';

export default function useVisibleHandler(ref, handler, modal = false) {
  const handleHideDropdown = (event) => {
    if (event.key === 'Escape') {
      handler();
    }
  };

  const handleClick = (e) => {
    if (ref.current && !ref.current.contains(e.target)) {
      handler();
    }
  };

  useEffect(() => {
    document.addEventListener('keydown', handleHideDropdown, true);
    document.addEventListener('click', handleClick, true);
    if (!modal) {
      document.addEventListener('mouseleave', handleClick, true);
    }
    return () => {
      document.removeEventListener('keydown', handleHideDropdown, true);
      document.removeEventListener('click', handleClick, true);
      if (!modal) {
        document.removeEventListener('mouseleave', handleClick, true);
      }
    };
  });
}

我正在尝试用酶和Jest创建一个测试,以检查鼠标离开时视图是否不再可见。 这是我尝试实现的方法,但似乎无法找出如何有效运行鼠标离开处理程序,以便事件真正发生的方法。

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

import ActionsMenu from '~/components/ActionsMenu';

describe('ActionsMenu component', () => {
  it('Should close on mouseleave', () => {
    const actionsMenuWrapper = mount(
      <ActionsMenu>
        <p>Test</p>
      </ActionsMenu>
    );

    const buttonWrapper = actionsMenuWrapper
      .find({
        'data-testid': 'button-wrapper',
      })
      .at(0);

    expect(buttonWrapper.length).toBe(1);

    buttonWrapper.simulate('click');

    let actionList = actionsMenuWrapper
      .find({
        'data-testid': 'action-list',
      })
      .at(0);

    expect(actionList.length).toBe(1);

    expect(actionList.props().visible).toBeTruthy();

    let actionsMenuContainer = actionsMenuWrapper
      .find({ 'data-testid': 'actions-menu-container' })
      .at(0);

    actionsMenuWrapper.update();

    actionsMenuContainer.simulate('mouseenter');

    actionsMenuContainer = actionsMenuWrapper
      .find({ 'data-testid': 'actions-menu-container' })
      .at(0);

    actionsMenuContainer.simulate('mouseleave');

    actionList = actionsMenuWrapper
      .find({
        'data-testid': 'action-list',
      })
      .at(0);

    expect(actionList.props().visible).toBeFalsy();
  });
});

0 个答案:

没有答案