来自 Jest 和 React-testing-library 单元测试的 useRef 的 ref 为 null

use*_*457 6 unit-testing reactjs jestjs react-testing-library

我有以下组件,我在导航上创建 ref 以在导航外部单击时关闭菜单:

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

const Header = () => {
  const [menuOpen, setMenuOpen] = useState(false);
  const navRef = useRef(null);

  const hideMenu = () => setMenuOpen(false);

  const handleClick = event => {
    if (menuOpen && !navRef.current.contains(event.target)) {
      hideMenu();
    }
  };

  useEffect(() => {
    document.addEventListener('click', handleClick);
    return () => {
      document.removeEventListener('click', handleClick);
    };
  });

  return (
    <header className="header">
      <nav className="header-nav" ref={navRef}>
        ...
      </nav>
    </header>
  );
};

export default Header;
Run Code Online (Sandbox Code Playgroud)

这是单元测试:

import React from 'react';

import '@testing-library/jest-dom';
import { cleanup, fireEvent } from '@testing-library/react';
import renderer from 'react-test-renderer';

import Header from './Header';
const { act } = renderer;

afterEach(cleanup);

describe('Header', () => {
  test('should open and close mobile menu', () => {
    const headerComponent = renderer.create(<Header />);
    const headerRoot = headerComponent.root;
    const navContainer = headerRoot.findByType('nav');

    act(() => {
      // open menu
      navContainer.children[0].props.onClick(new MouseEvent('click'));
    });
    act(() => {
      // click on document
      fireEvent(document, new MouseEvent('click'));
    });
    headerTree = headerComponent.toJSON();
    expect(headerTree).toMatchSnapshot();
  });
});
Run Code Online (Sandbox Code Playgroud)

测试运行结果出现以下错误:

    TypeError: Cannot read property 'contains' of null

      26 |
      27 |   const handleClick = (event) => {
    > 28 |     if (menuOpen && !navRef.current.contains(event.target)) {
         |                                     ^
      29 |       hideMenu();
      30 |     }
      31 |   };
Run Code Online (Sandbox Code Playgroud)

我试图嘲笑ref.currrent但它仍然是null

jest.spyOn(React, 'useRef').mockReturnValue({
  current: navContainer,
});
Run Code Online (Sandbox Code Playgroud)

请建议我如何组织测试来测试这个

PS我找到了这个答案,但它不适合我,因为我不想将 ref 作为道具传递:/sf/answers/4144503681/