1

I need your help on fixing the test case. I am trying to mock the document body offsetwidth, offsetLeft objects.

In the resize method, I am trying to mock the newWidth which is calculating the mouse position and accordingly getting the actual width and resizing the material UI modal.

index.tsx Following is the section from where I am triggering the enableResize on mousedown event.

 <div onMouseDown={enableResize} className={classes.dragger} />
    

useResize.tsx

  import {
  Dispatch,
  SetStateAction,
  useCallback,
  useEffect,
  useState,
} from 'react';

type UseResizeProps = {
  minWidth: number;
  maxWidth: number;
};

type UseResizeReturn = {
  width: number;
  enableResize: () => void;
  disableResize: () => void;
  isResizing: boolean;
  resize: (e: MouseEvent) => void;
  setWidth: Dispatch<SetStateAction<number>>;
};

const useResize = ({ minWidth, maxWidth }: UseResizeProps): UseResizeReturn => {
  const [isResizing, setIsResizing] = useState(false);
  const [width, setWidth] = useState(minWidth);

  const enableResize = useCallback(() => {
    setIsResizing(true);
  }, [setIsResizing]);

  const disableResize = useCallback(() => {
    setIsResizing(false);
  }, [setIsResizing]);

  const resize = useCallback(
    (e: MouseEvent) => {
      if (isResizing) {
        const newWidth =
          document.body.offsetWidth - (e.clientX - document.body.offsetLeft);
        if (newWidth > minWidth && newWidth < maxWidth) {
          setWidth(newWidth);
        }
      }
    },
    [minWidth, maxWidth, isResizing, setWidth],
  );

  useEffect(() => {
    document.addEventListener('mousemove', resize);
    document.addEventListener('mouseup', disableResize);

    return () => {
      document.removeEventListener('mousemove', resize);
      document.removeEventListener('mouseup', disableResize);
    };
  }, [disableResize, resize]);

  return {
    width,
    enableResize,
    isResizing,
    disableResize,
    resize,
    setWidth,
  };
};

export default useResize;
       

useResize.test.tsx

    const { result } = renderHook(() => useResize(defaultProps));
    const event = new MouseEvent('mousedown', {
      bubbles: true,
      clientX: 1000,
    });

    act(() => {
      result.current.resize(event);
      result.current.enableResize();
    });
    expect(result.current.isResizing).toBeTruthy();

    Object.defineProperty(document.body, 'offsetWidth', {
      value: 1536,
    });

    Object.defineProperty(document.body, 'offsetLeft', {
      value: 0,
    });

    const width: any =
      document.body.offsetWidth - (event.clientX - document.body.offsetLeft);

    window.dispatchEvent(new Event('resize'));

    expect(defaultProps.minWidth).toBeLessThan(width);

    act(() => {
      result.current.setWidth(width);
    });

    expect(result.current.width).toBe(536);
  });
2
  • What's the issue? Commented Jul 14, 2022 at 9:59
  • @slideshowp2 I am stuck in to test this condition and the set state setwidth method if (newWidth > minWidth && newWidth < maxWidth) { setWidth(newWidth); } Thanks in Advance. Commented Jul 15, 2022 at 6:08

1 Answer 1

0

If we only focus on the unit testing for the useResize hook, a simulated mousedown event to enable the resizing is unnecessary. We can call the enableResize function directly to change the isResizing state.

Instead of Event, we can create and dispatch a MouseEvent with mousemove type and clientX value.

E.g:

useResize.test.tsx:

import { renderHook, act } from '@testing-library/react-hooks';
import useResize from './useResize';

describe('72926548', () => {
  test('should set new width', async () => {
    const { result } = renderHook(() => useResize({ minWidth: 100, maxWidth: 200 }));
    act(() => {
      result.current.enableResize();
    })
    expect(result.current.isResizing).toBeTrue();
    Object.defineProperty(document.body, 'offsetWidth', {
      value: 1150,
    });
    Object.defineProperty(document.body, 'offsetLeft', {
      value: 0,
    });
    act(() => {
      document.dispatchEvent(new MouseEvent('mousemove', { clientX: 1000 }));
    })
    expect(result.current.width).toBe(150);
  });
});

Test result:

 PASS  stackoverflow/72926548/useResize.test.tsx (6.32 s)
  72926548
    ✓ should set new width (14 ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |   95.24 |    66.67 |   83.33 |   95.24 |                   
 useResize.tsx |   95.24 |    66.67 |   83.33 |   95.24 | 32                
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.615 s, estimated 7 s

package versions:

"@testing-library/react-hooks": "^8.0.1",
"jest": "^26.6.3",
"react": "^16.14.0",
"react-dom": "^16.14.0"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.