为 material-ui 实施 createMatchMedia()。我在尝试测试按钮时使用 material ui 隐藏组件来隐藏它们
Implementing createMatchMedia() for material-ui. I'm using a material ui hidden component to hide buttons while I'm trying to test them
我正在使用 React-testing-library getByText 查找被名为 Hidden 的 material ui 组件隐藏的按钮。由于 RTL 找不到它,Material ui 在这里 https://material-ui.com/components/use-media-query/#testing 有一个实现。但我无法弄清楚如何实现它来简单地找到一个按钮。一旦我删除 Hidden,该按钮就位于,我只是不确定如何在我的测试中使用他们的 createMatchMedia() 进行查询。
隐藏组件将我的按钮隐藏在 959px 及以下。
import React from "react"
import { render } from '../../../../test/test-utils'
import Collections from "./Collections"
import userEvent from '@testing-library/user-event'
import mediaQuery from 'css-mediaquery'
function createMatchMedia(width: any) {
return (query: string): any => ({
matches: mediaQuery.match(query, { width }),
addListener: () => {},
removeListener: () => {},
});
}
type CollectionsProps = React.ComponentProps<typeof Collections>
const baseProps: CollectionsProps = {
setValue: () => {},
setSelectedIndex: () => {},
pageStyle: {},
pageAnimations: {transition : {}, variants: {}},
motions: {animate:'', initial: '', exit: ''},
jumpTo: (jumpingTarget: string | number | Element): void => {}
}
const renderUI = (props: Partial<CollectionsProps>) =>
render(<Collections {...baseProps} {...props} />, {})
describe('When a filter is clicked', () => {
beforeAll( () => {
window.matchMedia = createMatchMedia(window.innerWidth)
})
let { getByText } = renderUI({})
test('items shown are only related to the picked Category', () => {
userEvent.click(getByText(/Team Colors/))
})
})
RTL 不是这里的问题。问题出在 jsdom which doesn't have an implementation of matchMedia()
. Jest uses jsdom internally and without an existing matchMedia()
no media query will match in Material UI's Hidden API.
- 您可以先安装 NPM 包来解决这个问题 css-mediaquery and @types/css-mediaquery。
- 然后像这样为
matchMedia
创建一个模拟:
// matchMedia.mock.ts
export const createMatchMedia = (width: number) => (query: string): MediaQueryList => ({
matches: mediaQuery.match(query, { width }),
media: query,
onchange: null,
addListener: () => jest.fn(),
removeListener: () => jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn()
});
window.matchMedia = createMatchMedia(window.innerWidth);
export default {};
- 在
setupTest.ts
(您的 Jest 测试设置文件)中导入上面的模拟文件,如下所示:
// setupTests.ts
import './__mocks__/matchMedia.mock';
...
- 像往常一样编写测试。无需使用
beforeAll()
创建新的 window.matchMedia
。模拟文件会为您处理。
我正在使用 React-testing-library getByText 查找被名为 Hidden 的 material ui 组件隐藏的按钮。由于 RTL 找不到它,Material ui 在这里 https://material-ui.com/components/use-media-query/#testing 有一个实现。但我无法弄清楚如何实现它来简单地找到一个按钮。一旦我删除 Hidden,该按钮就位于,我只是不确定如何在我的测试中使用他们的 createMatchMedia() 进行查询。
隐藏组件将我的按钮隐藏在 959px 及以下。
import React from "react"
import { render } from '../../../../test/test-utils'
import Collections from "./Collections"
import userEvent from '@testing-library/user-event'
import mediaQuery from 'css-mediaquery'
function createMatchMedia(width: any) {
return (query: string): any => ({
matches: mediaQuery.match(query, { width }),
addListener: () => {},
removeListener: () => {},
});
}
type CollectionsProps = React.ComponentProps<typeof Collections>
const baseProps: CollectionsProps = {
setValue: () => {},
setSelectedIndex: () => {},
pageStyle: {},
pageAnimations: {transition : {}, variants: {}},
motions: {animate:'', initial: '', exit: ''},
jumpTo: (jumpingTarget: string | number | Element): void => {}
}
const renderUI = (props: Partial<CollectionsProps>) =>
render(<Collections {...baseProps} {...props} />, {})
describe('When a filter is clicked', () => {
beforeAll( () => {
window.matchMedia = createMatchMedia(window.innerWidth)
})
let { getByText } = renderUI({})
test('items shown are only related to the picked Category', () => {
userEvent.click(getByText(/Team Colors/))
})
})
RTL 不是这里的问题。问题出在 jsdom which doesn't have an implementation of matchMedia()
. Jest uses jsdom internally and without an existing matchMedia()
no media query will match in Material UI's Hidden API.
- 您可以先安装 NPM 包来解决这个问题 css-mediaquery and @types/css-mediaquery。
- 然后像这样为
matchMedia
创建一个模拟:
// matchMedia.mock.ts
export const createMatchMedia = (width: number) => (query: string): MediaQueryList => ({
matches: mediaQuery.match(query, { width }),
media: query,
onchange: null,
addListener: () => jest.fn(),
removeListener: () => jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn()
});
window.matchMedia = createMatchMedia(window.innerWidth);
export default {};
- 在
setupTest.ts
(您的 Jest 测试设置文件)中导入上面的模拟文件,如下所示:
// setupTests.ts
import './__mocks__/matchMedia.mock';
...
- 像往常一样编写测试。无需使用
beforeAll()
创建新的window.matchMedia
。模拟文件会为您处理。