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
相关产品推荐
相关产品推荐

