简体   繁体   中英

Cannot unit test useClickAway with ReactTestUtils

I'm trying to test a component that uses useClickAway from react-use .

This is my component:

export default function DropdownMenu(props: DropdownMenuProps) {
  const { className, align, children } = props;
  const dropdownRef = React.useRef(null);
  const [isDropdownActive, setIsDropdownActive] = React.useState(false);
  useClickAway(dropdownRef, () => setIsDropdownActive(false));
  return (
    <div
      data-id="dropdown-parent"
      ref={dropdownRef}
      className={classes(
        "dropdown is-pulled-right",
        align === "right" && "is-right",
        isDropdownActive && "is-active"
      )}
    >
      <div className="dropdown-trigger">
        <button
          data-id="dropdown-button"
          onClick={() => setIsDropdownActive(!isDropdownActive)}
          className={classes("button is-dark is-radiusless", className)}
          aria-haspopup="true"
        >
          <span className="icon is-small">
            <i className="fas fa-ellipsis-v" aria-hidden="true" />
          </span>
        </button>
      </div>
      <div className="dropdown-menu" role="menu">
        <div className={classes("dropdown-content", styles.dropdown)}>
          {children}
        </div>
      </div>
    </div>
  );
}

and this is my test:

it('gets deactivated when area outside of dropdown is clicked', () => {
  const container = document.createElement('div');
  document.body.appendChild(container);
  ReactTestUtils.act(() => {
    ReactDOM.render(
      <div>
        <button data-id="outside"/>
        <DropdownMenu>
          <div/>
        </DropdownMenu>
      </div>, 
    container);
  })
  const button = container.querySelector('button[data-id="dropdown-button"]') as Element
  const parent = container.querySelector('div[data-id="dropdown-parent"]') as Element
  const outside = container.querySelector('button[data-id="outside"]') as Element
  ReactTestUtils.act(() => {
    ReactTestUtils.Simulate.click(button);
  })
  expect(parent.className).toContain('is-active') //<--- this works
  ReactTestUtils.act(() => {
    ReactTestUtils.Simulate.click(outside);
  })
  expect(parent.className).not.toContain('is-active') //<--- this doesn't
})

I tried using console.log in useClickAway callback. However, it doesn't seem to be called..

Am I missing something?

useClickAway uses mousedown event: https://github.com/streamich/react-use/blob/v13.27.0/src/useClickAway.ts#L4

With react-testing-library:

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

test('click away', () => {
  const { getByText } = render(<MyComponent />);

  // Does not work
  //getByText('outside').click();

  // Does work
  fireEvent.mouseDown(getByText('outside'));
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM