Jest.js 如何为不同的屏幕尺寸编写单元测试用例?

x759pob2  于 2023-05-21  发布在  Jest
关注(0)|答案(2)|浏览(199)

我有两个按钮显示的基础上,屏幕大小(为中等屏幕一个按钮和另一个按钮为其他屏幕)。我使用Material UI的MediaQuery和theme.breakpoints来定义屏幕大小。
这是我的UI代码,我在React中使用了 *Typescript *。

import React from "react";
import Button from "@material-ui/core/Button";
import useMediaQuery from "@material-ui/core/useMediaQuery";
import { useTheme } from "@material-ui/core/styles";

export default function SimpleCard() {
  const theme = useTheme();
  const isMd = useMediaQuery(theme.breakpoints.only("md"));

  return (
   <div>
    {isMd ? (
      <Button
       data-testid="mediumScreenButton"
       onClick={() => console.log("medium")}
      >
       medium screen
      </Button>
     ) : (
      <Button
       data-testid="otherScreenButton"
       onClick={() => console.log("other")}
      >
       Other screen
      </Button>
     )}
   </div>
 );
}

这是我的测试代码

import React from 'react';
import { render, fireEvent, screen, waitFor, cleanup } from '@testing-library/react';
import Demo from './Demo'

beforeEach(() =>
{
 window.scrollTo = jest.fn();
 window.HTMLDivElement.prototype.scrollIntoView = jest.fn();

 // window.matchMedia('(max-width: 999px)');

});

describe('To test cond. for screen sizes', () =>
 {
  afterEach(cleanup);

  it('Medium screen', async () =>
   {
    const { container } = render(<Demo />)

    const mediumScreenButton = screen.getByTestId('mediumScreenButton');
    fireEvent.click(mediumScreenButton);

    expect(container).toMatchSnapshot();

   });

});

我不明白如何在我的测试文件中将屏幕大小设置为中等,这样我的测试用例就可以通过。但是现在,测试用例失败了,因为“无法找到带有数据testidmediumScreenButton的元素”。有人能帮我解决这个问题吗?
谢谢你。

kyks70gy

kyks70gy1#

Mui文档有一些关于如何做到这一点的例子。
您需要在测试环境中实现matchMedia。
例如,jsdom还不支持它。你应该用polyfill填充。建议使用css-mediaquery来模拟它。
首先安装css-mediaquery

npm install css-mediaquery
// OR
yarn add css-mediaquery

你的测试可能是:

import mediaQuery from "css-mediaquery";
import Demo from './Demo'

const createMatchMedia = (width) => (query) => ({
  matches: mediaQuery.match(query, { width }),
  addListener: () => {},
  removeListener: () => {}
});

describe("Media Test", () => {
  it("Desktop Test", async () => {
    window.matchMedia = createMatchMedia(1000);

    render(<Demo />);

    const buttonEl = screen.getByRole("button");

    expect(buttonEl).toHaveTextContent("medium screen");
  });

  it("Mobile Test", async () => {
    window.matchMedia = createMatchMedia(200);

    render(<Demo />);

    const buttonEl = screen.getByRole("button");

    expect(buttonEl).toHaveTextContent("Other screen");
  });
});
  • 关于你的代码的提示:

避免使用getByTestId查找testing-library元素。在自己的文档中有一个查询优先级的建议,大家可以在这里查看。因此,在本例中,您可以使用getByRole('button')

6xfqseft

6xfqseft2#

我在项目中使用Typescript。下面的代码是为我工作。感谢@Luis的提示。
安装css-mediaquery

npm install css-mediaquery

在测试文件中添加此函数

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

最后把这个放在你的测试用例中(it)

createMatchMedia('999px');

总体测试代码为

import React from 'react';
import { render, fireEvent, screen, cleanup } from '@testing-library/react';
import Demo from './Demo'
import mediaQuery from 'css-mediaquery'; // install this package

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

beforeEach(() =>
 {
  window.scrollTo = jest.fn();
  window.HTMLDivElement.prototype.scrollIntoView = jest.fn();

 });

describe('To test cond. for screen sizes', () =>
 {
  afterEach(cleanup);

  it('Medium screen', async () =>
   {
    createMatchMedia('999px');
    const { container } = render(<Demo />)

    const mediumScreenButton = screen.getByTestId('mediumScreenButton');
    fireEvent.click(mediumScreenButton);

    expect(container).toMatchSnapshot();

   });

});

相关问题