yocontra / react-responsive

CSS media queries in react - for responsive design, and more.
https://contra.io/react-responsive
MIT License
6.95k stars 297 forks source link

Mocking the media values #316

Closed kvaithin closed 1 year ago

kvaithin commented 1 year ago

Felt the right place to be asking this as most would be familiar with this project. Apologies if this is the wrong place to be asking this.

I am trying to test the following implementation.

    import React from "react";
    import { useMediaQuery } from "react-responsive";

    const MyComponent = () => {
      const isSM = useMediaQuery({ maxWidth: 767 });
      const isMD = useMediaQuery({ minWidth: 768, maxWidth: 1023 });
      const isLG = useMediaQuery({ minWidth: 1024 });

      console.log(`isSM:${isSM} isMD:${isMD} isLG:${isLG}`);

      return <>{`isSM:${isSM} isMD:${isMD} isLG:${isLG}`}</>;
    };

    export default MyComponent;

How can I mock it so that isLG can be set to true? And similarly to be able to set isSM and isMD to be true for other tests?

Tried the following but all 3 (isSM, isMD, isLG) are always false.

    import React from 'react';
    import { mount } from 'enzyme';

    function mockMatchMedia(query) {
        return Object.defineProperty(window, 'matchMedia', {
            writable: true,
            value: jest.fn().mockImplementation((mediaQuery) => ({
            matches: mediaQuery.includes(query),
            media: mediaQuery,
            onchange: null,
            addListener: jest.fn(), 
            removeListener: jest.fn(),
            addEventListener: jest.fn(),
            removeEventListener: jest.fn(),
            dispatchEvent: jest.fn(),
            })),
        });
    }

    test("renders the component", () => {
        mockMatchMedia('min-width: 1024px');
        mount(<MyComponent />);

        // the console log in component prints false for all wrongly. 
        // Was expecting isLG to be true.

        // assertions
    }

Seen the following within this project.

https://github.com/yocontra/react-responsive/blob/master/test/useMediaQuery_test.tsx

import { MatchMediaMock } from 'match-media-mock'

(window as unknown as MockWindow).matchMedia.setConfig({
    type: 'screen',
    width: 1200,
    height: 800
  })

This doesn't mock it either, is false for all 3 break points.

yocontra commented 1 year ago

See https://github.com/yocontra/react-responsive#testing (using the device property)