How to test addEventListener with jest and testing library?

54 Views Asked by At

I created a custom hook in reactJS that listens to changes in elements dimensions and then calculates the width and height of the element.

export function useDynamicDimensions(element) {
  const [ width, setWidth ] = useState(element?.innerWidth);
  const [ height, setHeight ] = useState(element?.innerHeight);

  useEffect(() => {
    const handleWindowResize = () => {
      setWidth(element?.innerWidth);
      setHeight(element?.innerHeight);
    };

    element?.addEventListener('resize', handleWindowResize);

    return () => element?.removeEventListener('resize', handleWindowResize);
  }, []);

  return { width, height };
}

I wrote the following test case using Jest and the testing library.

  it('updates dimensions on window resize', () => {
    const initialWidth = 100;
    const initialHeight = 200;
    const newWidth = 250;
    const newHeight = 300;

    const element = {
      innerWidth: initialWidth,
      innerHeight: initialHeight,
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
    };

    const { result } = renderHook(() => useDynamicDimensions(element));

    expect(result.current.width).toBe(initialWidth);
    expect(result.current.height).toBe(initialHeight);

    act(() => {
      element.innerWidth = newWidth;
      element.innerHeight = newHeight;
      global.dispatchEvent(new Event('resize'));
    });

    expect(result.current.width).toBe(250);
  });

But this test case doesn't work. It gives an error

expect(received).toBe(expected)

    Expected: 250
    Received: 100

Can someone tell me where I am going wrong?

1

There are 1 best solutions below

0
Jake Cano On BEST ANSWER

Hey I found the answer to my own question :)

import React from 'react';
import { renderHook, act } from '@testing-library/react';

describe('useDynamicDimensions', () => {
  it('should return dimensions as is if there is no change in dimensions', () => {
    const initialWidth = 800;
    const initialHeight = 600;

    const map = {};

    const element = {
      innerWidth: initialWidth,
      innerHeight: initialHeight,
      addEventListener: jest.fn((event, cb) => {
        map[event] = cb;
      }),
      removeEventListener: jest.fn()
    };

    const { result } = renderHook(() => useDynamicDimensions(element));

    expect(result.current.width).toBe(initialWidth);
    expect(result.current.height).toBe(initialHeight);
  });

  it('should update dimensions on element resize', () => {
    const initialWidth = 800;
    const initialHeight = 600;

    const map = {};

    const element = {
      innerWidth: initialWidth,
      innerHeight: initialHeight,
      addEventListener: jest.fn((event, cb) => {
        map[event] = cb;
      }),
      removeEventListener: jest.fn()
    };

    const { result } = renderHook(() => useDynamicDimensions(element));

    act(() => {
      element.innerWidth = 500;
      element.innerHeight = 300;
      map.resize?.();
    });

    expect(result.current.width).toBe(500);
    expect(result.current.height).toBe(300);
  });
});