You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中useMediaQuery的Jest多返回值模拟失效问题排查

正确模拟Material UI useMediaQuery的Jest测试方案

问题根源

你犯了两个关键错误:

  1. useMediaQuery的返回值是单个布尔值,而非包含多个状态的对象,你之前的mock返回了对象,导致两个变量都被赋值为同一个对象。
  2. 两次调用useMediaQuery的参数不同,但你用mockReturnValue返回固定值,无法区分不同调用的返回结果。

正确模拟方案

方案一:按调用顺序返回值(适合简单场景)

如果代码中useMediaQuery的调用顺序固定(先print后断点查询),可以用mockReturnValueOnce依次指定返回值:

import { useMediaQuery } from '@mui/material';

// 先模拟print查询返回false,再模拟小屏幕查询返回true
useMediaQuery.mockReturnValueOnce(false)
             .mockReturnValueOnce(true);

注意:此方法依赖调用顺序,若代码中调用顺序变更,测试会失效。

方案二:按参数匹配返回值(更健壮)

通过mockImplementation根据传入的查询参数,返回对应的布尔值,适配任意调用顺序:

import { useMediaQuery } from '@mui/material';

jest.mock('@mui/material', () => ({
  ...jest.requireActual('@mui/material'),
  useMediaQuery: jest.fn((query) => {
    // 匹配print媒体查询
    if (query === 'print') {
      return false;
    }
    // 匹配基于theme的断点查询
    if (typeof query === 'function') {
      // 模拟Material UI的theme对象
      const mockTheme = {
        breakpoints: {
          down: (breakpoint) => breakpoint === 'md', // 匹配md断点以下的情况
          values: { md: 900 } // 对应你项目中实际的md断点像素值
        }
      };
      // 执行传入的theme函数,返回匹配结果
      return query(mockTheme);
    }
    // 默认返回false
    return false;
  })
}));

验证效果

修改mock后,你的代码中:

const isPrint = useMediaQuery('print') // 会返回false
const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down(theme.breakpoints.values.md)) // 会返回true

此时console.log(isSmallScreen, isPrint)会输出true false,符合预期。

内容的提问来源于stack exchange,提问作者keerti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 12:00:11