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

如何Mock window.matchMedia设置react-responsive的useMediaQuery断点状态?

如何正确Mock window.matchMedia测试react-responsive的useMediaQuery组件?

问题原因分析

  1. 自定义Mock失效原因:react-responsive会将你传入的配置对象(如{ minWidth: 1024 })转换为带括号的标准媒体查询字符串(比如(min-width: 1024px)),但你之前传入Mock的参数是min-width: 1024px(缺少括号),导致mediaQuery.includes(query)无法匹配,最终matches始终返回false。
  2. match-media-mock失效原因:之前的代码未确保Mock在组件渲染前完全生效,且使用react-test-renderer时缺少状态更新的断言时机,改用react-testing-library更适配这类DOM断言场景。

解决方案一:自定义Jest Mock

修正匹配逻辑,传入完整的媒体查询字符串进行精确匹配:

import { mount } from 'enzyme';
import MyComponent from './MyComponent';

function mockMatchMedia(expectedQuery) {
  Object.defineProperty(window, 'matchMedia', {
    writable: true,
    value: jest.fn().mockImplementation((mediaQuery) => ({
      matches: mediaQuery === expectedQuery,
      media: mediaQuery,
      onchange: null,
      addListener: jest.fn(),
      removeListener: jest.fn(),
      addEventListener: jest.fn(),
      removeEventListener: jest.fn(),
      dispatchEvent: jest.fn(),
    })),
  });
}

// 测试isLG为true的场景
test("renders with isLG true", () => {
  mockMatchMedia('(min-width: 1024px)');
  const wrapper = mount(<MyComponent />);
  
  expect(wrapper.text()).toContain('isLG:true');
});

// 测试isSM为true的场景
test("renders with isSM true", () => {
  mockMatchMedia('(max-width: 767px)');
  const wrapper = mount(<MyComponent />);
  
  expect(wrapper.text()).toContain('isSM:true');
});

// 测试isMD为true的场景
test("renders with isMD true", () => {
  mockMatchMedia('(min-width: 768px) and (max-width: 1023px)');
  const wrapper = mount(<MyComponent />);
  
  expect(wrapper.text()).toContain('isMD:true');
});

解决方案二:使用match-media-mock库

确保Mock在组件渲染前初始化,结合react-testing-library进行断言:

import { render, screen } from '@testing-library/react';
import { create } from 'match-media-mock';
import MyComponent from './MyComponent';

// 测试isSM(宽度700px)
test("shows isSM true when width is 700px", () => {
  const matchMedia = create();
  global.window.matchMedia = matchMedia;
  
  matchMedia.setConfig({ type: 'screen', width: 700 });
  
  render(<MyComponent />);
  
  expect(screen.getByText(/isSM:true/)).toBeInTheDocument();
});

// 测试isMD(宽度800px)
test("shows isMD true when width is 800px", () => {
  const matchMedia = create();
  global.window.matchMedia = matchMedia;
  
  matchMedia.setConfig({ type: 'screen', width: 800 });
  
  render(<MyComponent />);
  
  expect(screen.getByText(/isMD:true/)).toBeInTheDocument();
});

// 测试isLG(宽度1200px)
test("shows isLG true when width is 1200px", () => {
  const matchMedia = create();
  global.window.matchMedia = matchMedia;
  
  matchMedia.setConfig({ type: 'screen', width: 1200 });
  
  render(<MyComponent />);
  
  expect(screen.getByText(/isLG:true/)).toBeInTheDocument();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:24:55