【问题标题】:How to test a function that uses the window.screen.width in jest如何测试一个使用 window.screen.width 开玩笑的函数
【发布时间】:2021-07-04 02:35:47
【问题描述】:

我正在开玩笑中测试这个功能, 但我无法覆盖、调整屏幕大小或创建虚拟 dom。

我正在节点上运行此测试。 ps:我尝试使用jsdom但失败了。

functions.js

export const getScreenWidth = () => {
  const screenWidth = window.screen.width;
  if (screenWidth <= 425) return "mobile";
  if (screenWidth <= 768) return "tablet";
  if (screenWidth <= 1024) return "laptopSm";
  if (screenWidth <= 1440) return "laptopLg";
  if (screenWidth <= 2560) return "HD";
  return screenWidth;
};

【问题讨论】:

    标签: javascript jestjs window width screen


    【解决方案1】:

    可以通过覆盖全局屏幕变量来模拟屏幕。

    例子:

    const mockScreen = (size) => {
      const { screen } = window.screen;
      delete window.screen;
      window.screen = {
        ...screen,
        width: size
      };
    };
    
    test("getScreenWidth", () => {
      mockScreen(300);
      expect(getScreenWidth()).toBe("mobile");
      mockScreen(1025);
      expect(getScreenWidth()).toBe("laptopLg");
    });
    

    【讨论】:

    • 我收到了这个错误The error below may be caused by using the wrong test environment, see https://jestjs.io/docs/configuration#testenvironment-string. Consider using the "jsdom" test environment.
    【解决方案2】:

    我尝试制作这个模拟并且它有效,但我真的不知道这是否是正确的方法。

    const mockScreen = (size) => {
          global.window = {};
          global.window.screen = {};
          global.window.screen.width = size;
        };
    

    所以最终测试将是

    describe("getScreenWidth()", () => {
      it.only("returns a string representing the width of the screen", () => {
        const mockScreen = (size) => {
          global.window = {};
          global.window.screen = {};
          global.window.screen.width = size;
        };
        mockScreen(425);
        expect(jsf.getScreenWidth()).toBe("mobile");
        mockScreen(2560);
        expect(jsf.getScreenWidth()).toBe("HD");
      });
    });
    

    【讨论】:

      【解决方案3】:

      如果您使用反应测试库模拟这样的调整大小

      global.innerWidth = 1024;
      global.dispatchEvent(new Event('resize'));
      

      然后期望您的函数返回正确的大小

      我测试了一个自定义钩子,例如

      function useWindowSize() {
        const [width, setWidth] = useState(window.innerWidth);
        const [height, setHeight] = useState(window.innerHeight);
      
        useEffect(() => {
          const handleResize = () => {
            setWidth(window.innerWidth);
            setHeight(window.innerHeight);
          };
          window.addEventListener('resize', handleResize);
          return () => {
            window.removeEventListener('resize', handleResize);
          };
        });
      
        return { width, height };
      }
      

      这边

      function TestUseWindowSize() {
        const { height, width } = useWindowSize();
        return (
          <div>
            <h1 data-testid="height">{height}</h1>
            <h1 data-testid="width">{width}</h1>
          </div>
        );
      }
      
      describe('useWindowSize Custom Hook', () => {
        it('should return height and width', () => {
          const { getByTestId } = render(<TestUseWindowSize />);
          // screen defaults by render function
          expect(getByTestId('height')).toHaveTextContent(/768/);
          expect(getByTestId('width')).toHaveTextContent(/1024/);
      
          global.innerWidth = 1000;
          global.dispatchEvent(new Event('resize'));
          expect(getByTestId('width')).toHaveTextContent(/1000/);
        });
      });
      

      【讨论】:

        猜你喜欢
        • 2019-01-04
        • 2020-08-24
        • 1970-01-01
        • 2018-08-06
        • 2018-08-12
        • 2022-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多