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

How to test a function that uses the window.screen.width in jest

我正尝试在 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'));

然后期望您的函数return大小合适

我测试了一个自定义挂钩

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