Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ResizeObserver API testing jest

I tried to test the hook, that used the ResizeObserver. Also, I need to check if the element was overflow or wasn't after resizing. So I wrote such a decision:

import { useLayoutEffect, useState } from 'react';
import ResizeObserver from 'resize-observer-polyfill';

export default function useOverflowCheck(ref) {
  const [isOverflowing, setIsOverflowing] = useState(false);

  const isOverflow = current => {
    if (current) {
      const hasOverflowX = current.offsetWidth < current.scrollWidth;
      const hasOverflowY = current.offsetHeight < current.scrollHeight;

      setIsOverflowing(hasOverflowX || hasOverflowY);
    }
  };

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useLayoutEffect(() => {
    const element = ref.current;

    const resizeObserver = new ResizeObserver(entries => {
      entries && entries.length && isOverflow(entries[0].target);
    });

    if (element) {
      resizeObserver.observe(element);
      return () => {
        resizeObserver.disconnect();
      };
    }
  });

  return isOverflowing;
}

And I tried to unit test this code, but my tests didn't cover the resizeObserver callback. Test:

import { renderHook } from '@testing-library/react-hooks';
import useOverflowCheck from './index';

describe('useOverflowCheck', () => {
  it('should return true for an overflowing component', () => {
    const el: HTMLDivElement = document.createElement('div');
    Object.defineProperties(el, {
      offsetWidth: { value: 30, configurable: true },
      offsetHeight: { value: 30, configurable: true },
    });

    const ref = {
      current: el,
    };

    expect(renderHook(() => useOverflowCheck(ref)).result.current).toBeTruthy();
  });
});
like image 427
Yumie Avatar asked Oct 23 '25 03:10

Yumie


1 Answers

Should define Resize Observer constructor and add a listener to test Resize Observer callback.

let listener: ((rect: any) => void) | undefined = undefined;
    (global as any).ResizeObserver = class ResizeObserver {
      constructor(ls) {
        listener = ls;
      }
      observe() {}
      unobserve() {}
      disconnect() {}
    };

Then should specify needed properties:

act(() => {
      listener!([
        {
          target: {
            clientWidth: 100,
            scrollWidth: 200,
            clientHeight: 100,
            scrollHeight: 200,
          },
        },
      ]);
    });

Inspired by https://github.com/streamich/react-use/blob/master/tests/useMeasure.test.ts

like image 91
Yumie Avatar answered Oct 24 '25 19:10

Yumie



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!