React - Jest - Test preventDefault Action

Viewed 4451

I don't know how to test key down event & prevent default. Test reached code but preventDefault has never been called: Received number of calls: 0

React Component - App.js

  const onKeyDown = e => {
      console.log("==== TEST REACHED HERE ====")
      e.preventDefault(); // NEVER CALLED ???
  };
  useEffect(() => {
    document.addEventListener("keydown", onKeyDown, false);
    return () =>
      document.removeEventListener("keydown", onKeyDown, false);
  }, []);

Unit test

it("should prevent default action on key down", () => {
   const { getByRole } = render(<App {...props} />);
   const grid = getByRole("app");
   const mockEvent = { preventDefault: jest.fn() };
   fireEvent.keyDown(grid, mockEvent);
   expect(mockEvent.preventDefault).toHaveBeenCalledTimes(1);
});

enter image description here

2 Answers

I found a more explicit way than accepted answer. You can use createEvent from 'react-testing-library' to manually create the event before firing it.

it("should prevent default action on key down", () => {
  const { getByRole } = render(<App {...props} />);
  const grid = getByRole("app");
  const keyDownEvent = createEvent.keyDown(grid);
   
  fireEvent(grid, keyDownEvent);
   
  expect(keyDownEvent.defaultPrevented).toBe(true);
});

I think this method can be reused to test other things than defaultPrevented !

It seems that you can not mock preventDefault property of the event with react testing library.

Under the hook, fireEvent is calling dispatchEvent, so you can take advantage of the fact that calling event.preventDefault returns false if the event is cancelled:

it("should prevent default action on key down", () => {
   const { getByRole } = render(<App {...props} />);
   const grid = getByRole("app");
   const isPrevented = fireEvent.keyDown(grid);
   expect(isPrevented).toBe(false);
});
Related