Jestjs 开玩笑+;物料界面:正确模拟useMediaQuery

Jestjs 开玩笑+;物料界面:正确模拟useMediaQuery,jestjs,material-ui,Jestjs,Material Ui,我正在我的一个组件中使用Material UI的useMediaQuery()函数来确定组件中使用的大小道具 我试图在jest测试中测试它是否如预期工作,但是我当前的实现不工作: description(“单位:在xs屏幕上)”,()=>{ //错误地将'matches'返回为'false'**************************** window.matchMedia=jest.fn().mockImplementation( 查询=>{ 返回{ 匹配:对, 媒体:质疑,, onc

我正在我的一个组件中使用Material UI的
useMediaQuery()
函数来确定组件中
使用的
大小
道具

我试图在jest测试中测试它是否如预期工作,但是我当前的实现不工作:

description(“单位:在xs屏幕上)”,()=>{
//错误地将'matches'返回为'false'****************************
window.matchMedia=jest.fn().mockImplementation(
查询=>{
返回{
匹配:对,
媒体:质疑,,
onchange:null,
addListener:jest.fn(),
removeListener:jest.fn()
};
}
);
它(“呈现为快照”,异步()=>{
const width=theme.breakpoints.values.sm-1;
常数高度=数学圆((宽度*9)/16);
Object.defineProperty(窗口“innerWidth”{
可写:对,
对,,
值:宽度
});
const{asFragment}=render(
);
expect(asFragment()).toMatchSnapshot();
const屏幕截图=等待生成图像({
视口:{宽度,高度}
});
expect(屏幕截图).toMatchImageSnapshot();
});
});
描述(“单位:在md和up屏幕上)”,()=>{
//将'matches'正确返回为'false'****************************
window.matchMedia=jest.fn().mockImplementation(
查询=>{
返回{
匹配项:false,
媒体:质疑,,
onchange:null,
addListener:jest.fn(),
removeListener:jest.fn()
};
}
);
它(“呈现为快照”,异步()=>{
常量宽度=theme.breakpoints.values.md;
常数高度=数学圆((宽度*9)/16);
Object.defineProperty(窗口“innerWidth”{
可写:对,
对,,
值:宽度
});
const{asFragment}=render(
);
expect(asFragment()).toMatchSnapshot();
const屏幕截图=等待生成图像({
视口:{宽度,高度}
});
expect(屏幕截图).toMatchImageSnapshot();
});
});
以及我正在测试的组件(删除了不相关的部分):

const导航栏=()=>{
const theme=useTheme();
const matchXs=useMediaQuery(theme.breakpoints.down(“xs”);
返回(
登录
);
};
导出默认导航栏;
对于第一次测试,它返回
匹配
,即使我已将其设置为返回真。我知道这一点,因为它正在生成一个屏幕截图,我可以看到第一次测试时按钮大小设置为
large
,而应该设置为
medium

它在生产中的工作情况与预期一致

如何在jest测试中正确地获得mock
useMediaQuery()

我找到了答案

useMediaQuery()
需要重新渲染组件才能工作,因为第一次渲染将返回您在
选项中定义的任何内容。默认匹配
默认为false

此外,模拟需要限定到每个测试(
it
)的范围,而不是在
description

当我使用react测试库时,我所要做的就是再次重新呈现组件,并更改模拟的范围,它就可以工作了

以下是工作示例:

const initTest=width=>{
Object.defineProperty(窗口“innerWidth”{
可写:对,
对,,
值:宽度
});
window.matchMedia=jest.fn().mockImplementation(
查询=>{
返回{
匹配:width>=theme.breakpoints.values.sm?true:false,
媒体:质疑,,
onchange:null,
addListener:jest.fn(),
removeListener:jest.fn()
};
}
);
常数高度=数学圆((宽度*9)/16);
返回{宽度,高度};
};
描述(“单位:在xs屏幕上”,()=>{
它(“呈现为快照”,异步()=>{
const{width,height}=initTest(theme.breakpoints.values.sm-1);
const{asFragment,rerender}=render(
);
复卷机(
);
expect(asFragment()).toMatchSnapshot();
const屏幕截图=等待生成图像({
视口:{宽度,高度}
});
expect(屏幕截图).toMatchImageSnapshot();
});
});
描述(“单位:在md和up屏幕上)”,()=>{
它(“呈现为快照”,异步()=>{
const{width,height}=initTest(theme.breakpoints.values.md);
const{asFragment}=render(
);
复卷机(
);
expect(asFragment()).toMatchSnapshot();
const屏幕截图=等待生成图像({
视口:{宽度,高度}
});
expect(屏幕截图).toMatchImageSnapshot();
});
});

推荐的方法是使用以下内容:

从“css mediaQuery”导入mediaQuery;
函数createMatchMedia(宽度){
返回查询=>({
匹配:mediaQuery.match(查询,{width}),
addListener:()=>{},
removeListener:()=>{},
});
}
描述('MyTests',()=>{
以前(()=>{
window.matchMedia=createMatchMedia(window.innerWidth);
});
});

我认为最好将接受答案更改为我的答案,因为这是基于文档的最新解决方案。我认为最好将接受答案更改为我的答案,因为这是基于文档的最新解决方案。