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

Jest测试报错TypeError: window.matchMedia is not a function如何解决

依赖matchMedia的响应式组件快照测试方案

1. 编写matchMedia模拟文件(matchMedia.mock.ts)

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

这个导出的方法可以自定义matches的返回值,用来模拟当前视口是否匹配你写的媒体查询规则:传true对应模拟移动端(视口宽度<=600px),传false对应模拟桌面端。

2. 示例代码字段说明

你参考示例里的myMethod就是待测试文件导出的目标内容,你的场景里待测试的是CalendarTitle组件,对应就是你组件文件导出的组件对象。

3. 完整测试代码实现

注意要先执行matchMedia的模拟,再导入测试依赖的组件,避免组件依赖的响应式判断逻辑在mock生效前就执行:

import renderer from 'react-test-renderer';
import mockMatchMedia from './matchMedia.mock.ts';

// 先模拟桌面端场景(matches为false)
mockMatchMedia(false);
// 模拟完成后再导入组件
import CalendarTitle from './你的CalendarTitle组件路径';

test('CalendarTitle 桌面端快照正常', () => {
  const component = renderer.create(<CalendarTitle month={8} year={2021} />);
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

// 模拟移动端场景
test('CalendarTitle 移动端快照正常', () => {
  // 重置mock,重新设置为移动端匹配
  mockMatchMedia(true);
  // 清除之前的模块缓存,重新导入组件触发响应式判断
  jest.resetModules();
  const MobileCalendarTitle = require('./你的CalendarTitle组件路径').default;
  const component = renderer.create(<MobileCalendarTitle month={8} year={2021} />);
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

简化方案

如果你的响应式判断逻辑是单独抽离的文件,可以直接mock这个独立文件,不需要额外写matchMedia的mock:

// 在测试文件顶部直接mock你的响应式判断文件
jest.mock('./你的响应式判断文件路径', () => ({
  __esModule: true,
  default: false, // 这里直接指定返回值,false是桌面端,true是移动端
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:39:03