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

问题描述 投票:0回答:2

我有两个按钮根据屏幕尺寸显示(对于中屏幕,一个按钮,对于其他屏幕,另一个按钮)。我使用 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 的元素”。 有人可以帮我解决这个问题吗?

谢谢你。

unit-testing react-hooks jestjs material-ui react-testing-library
2个回答
5
投票
Mui

docs 有一些关于如何操作的示例。

您需要在测试环境中实现 matchMedia。


例如,jsdom还不支持它。你应该填充它。建议使用
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
 的元素。在他们的文档中有一个查询优先级建议,您可以查看
here。因此,根据您的情况,您可以使用 getByRole('button')

    


3
投票
我在我的项目中使用 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(); }); });
    
© www.soinside.com 2019 - 2024. All rights reserved.