如何在玩笑中测试使用 window.screen.width 的函数

问题描述

我正在尝试在 jest 中测试此功能, 但我无法覆盖、调整屏幕大小或创建虚拟 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;
};

解决方法

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

示例:

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");
});
,

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

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");
  });
});
,

如果你使用 react 测试库模拟这样的调整大小

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/);
  });
});