测试悬停状态挂钩

时间:2020-07-25 02:52:18

标签: javascript reactjs react-testing-library

我创建了这个useHover钩子:

import { useRef, useState, useEffect } from 'react';

export const useHover = () => {
  const [value, setValue] = useState(false);

  const ref = useRef(null);

  const handleMouseOver = () => setValue(true);
  const handleMouseOut = () => setValue(false);

  useEffect(
    // eslint-disable-next-line consistent-return
    () => {
      const node = ref.current;
      if (node) {
        node.addEventListener('mouseover', handleMouseOver);
        node.addEventListener('mouseout', handleMouseOut);

        return () => {
          node.removeEventListener('mouseover', handleMouseOver);
          node.removeEventListener('mouseout', handleMouseOut);
        };
      }
    },
    []
  );

  return [ref, value];
};

我写了这个测试:

import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import { fireEvent, render } from '@testing-library/react';
import { Box } from 'gestalt';
import userEvent from '@testing-library/user-event';
import { useHover } from './useHover';

describe('useHover', () => {
  it('toogles', async () => {
    const { result } = renderHook(() => useHover());

    // eslint-disable-next-line no-unused-vars
    const [ref, value] = result.current;
    expect(value).toBeFalsy();

    const Div = () => <Box ref={ref}>Test</Box>;

    render(<Div />);

    await userEvent.hover(ref.current);
    expect(value).toBeTruthy();

    fireEvent.mouseOut(ref.current);
    expect(value).toBeFalsy();
  });
});

但是失败了:

21 | Expect(value).toBeTruthy();

1 个答案:

答案 0 :(得分:0)

乍一看,我看到了一些可能的问题

  1. useEffect的依赖关系数组为空,这只会在第一次在组件中调用useEffect时触发。
  2. 第一次使用useEffect挂载该节点时,该节点总是虚假的,因此发生dom事件 听众将不会添加。 也许添加[ref.current]将解决 这参见第3点
  3. 使用ref.current作为依赖项数组中的依赖项通常不是一个好主意。
  4. “值”的值无论如何都不会改变,因为它已被分解为常量值类型,因此它将是该值类型的初始快照。
  5. dom事件侦听器与测试中“触发”的事件是不同的事件
  6. 建议改用useCallback挂钩,并在依赖项数组中查看自定义挂钩的回调函数
  7. 建议测试实际组件中的钩子,因为它依赖于链接到组件的dom事件

请参阅this codeSandBox

enter image description here