Javascript 为材质ui实现createMatchMedia()。I';I';我在试着测试它们

Javascript 为材质ui实现createMatchMedia()。I';I';我在试着测试它们,javascript,reactjs,typescript,material-ui,react-testing-library,Javascript,Reactjs,Typescript,Material Ui,React Testing Library,我正在使用React测试库getByText查找一个按钮,该按钮由名为hidden的材质ui组件隐藏。因为RTL找不到它,所以MaterialUI在这里实现了它。但我不知道如何实现它,只需找到一个按钮。一旦我删除隐藏,按钮就会被定位,我只是不知道如何在我的测试中使用createMatchMedia()进行查询 隐藏组件将我的按钮隐藏在959px及以下 import React from "react" import { render } from '../../../../t

我正在使用React测试库getByText查找一个按钮,该按钮由名为hidden的材质ui组件隐藏。因为RTL找不到它,所以MaterialUI在这里实现了它。但我不知道如何实现它,只需找到一个按钮。一旦我删除隐藏,按钮就会被定位,我只是不知道如何在我的测试中使用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/))
    })  
}) 
从“React”导入React
从“../../../../test/test-utils”导入{render}
从“/Collections”导入集合
从“@测试库/用户事件”导入userEvent
从“css mediaQuery”导入mediaQuery
函数createMatchMedia(宽度:任意){
返回(查询:字符串):any=>({
匹配:mediaQuery.match(查询,{width}),
addListener:()=>{},
removeListener:()=>{},
});
}
类型CollectionsProps=React.ComponentProps
const baseProps:CollectionsProps={
setValue:()=>{},
setSelectedIndex:()=>{},
页面样式:{},
页面动画:{转换:{},变体:{},
运动:{动画:'',初始:'',退出:'},
jumpTo:(jumpingTarget:string | number |元素):void=>{}
}
const renderUI=(道具:部分)=>
呈现(,{})
描述('单击筛选器时',()=>{
以前(()=>{
window.matchMedia=createMatchMedia(window.innerWidth)
})
让{getByText}=renderUI({})
测试('显示的项目仅与所选类别相关',()=>{
userEvent.click(getByText(/Team Colors/))
})  
}) 

RTL不是这里的问题。问题在于没有实现
matchMedia()
。Jest在内部使用jsdom,并且没有现有的
matchMedia()
任何媒体查询都不会在材质UI中匹配

  • 您可以通过首先安装NPM包和
  • 然后为
    matchMedia
    创建一个模拟,如下所示:
  • 将上面的模拟文件导入
    setupTest.ts
    (您的Jest测试设置文件),如下所示:
  • 像平常一样编写测试。无需使用
    beforeAll()
    创建新的
    窗口。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 {};
    
    // setupTests.ts
    import './__mocks__/matchMedia.mock';
    ...