javascript mock 测试中模拟窗口 resize 事件需用 object.defineproperty 修改 window.innerwidth/innerheight 并手动 dispatchevent,封装 mockresize 函数提升复用性,验证监听器调用并注意 jsdom 版本、媒体查询及框架生命周期适配。

在 JavaScript Mock 测试中模拟浏览器窗口大小调整(resize)事件,核心是手动触发 window 对象上的 resize 事件,并确保测试环境(如 Jest + JSDOM)支持该行为。关键在于:正确创建并派发事件、更新 window.innerWidth/window.innerHeight、避免依赖真实 DOM 尺寸。
修改 window.innerWidth/innerHeight 并触发 resize 事件
JSDOM 默认不响应窗口尺寸变化,需手动设置属性并触发事件:
- 用
Object.defineProperty重写innerWidth和innerHeight的 getter,使其返回期望值 - 调用
window.dispatchEvent(new Event('resize'))触发监听器 - 注意:直接赋值
window.innerWidth = 800无效(它是只读属性)
示例代码:
// Jest 测试中
Object.defineProperty(window, 'innerWidth', {
writable: true,
configurable: true,
value: 800
});
Object.defineProperty(window, 'innerHeight', {
writable: true,
configurable: true,
value: 600
});
window.dispatchEvent(new Event('resize'));
封装可复用的 mockResize 工具函数
为避免重复代码,可封装一个通用函数:
- 接收目标宽高,自动修改
innerWidth/innerHeight - 触发事件后可选等待微任务(确保异步监听器执行)
- 适合在
beforeEach或具体测试用例中调用
示例:
const mockResize = (width, height) => {
Object.defineProperty(window, 'innerWidth', { value: width });
Object.defineProperty(window, 'innerHeight', { value: height });
window.dispatchEvent(new Event('resize'));
return Promise.resolve(); // 可配合 await 使用
};
// 在测试中
await mockResize(1200, 800);
验证 resize 监听器是否被正确调用
若业务逻辑中监听了 window.addEventListener('resize', handler),需在测试中:
- 用
jest.fn()替换原始 handler,或在测试前 spyOn - 触发 resize 后断言 handler 被调用,且参数/内部逻辑符合预期
- 注意清理:测试后恢复原属性或重置 JSDOM 环境(如使用
jest.resetModules())
例如:
const handler = jest.fn();
window.addEventListener('resize', handler);
mockResize(768, 1024);
expect(handler).toHaveBeenCalledTimes(1);
注意事项与常见坑
实际模拟中容易忽略的细节:
- JSDOM 版本影响:v20+ 对
innerWidth支持更稳定,旧版本建议升级 - 媒体查询相关逻辑(如
window.matchMedia)需单独 mock,resize 事件本身不触发其变化 - React/Vue 等框架中,组件可能通过
useEffect或mounted注册 resize,需确保组件已挂载再 mock - 避免在多个测试间共享 window 属性修改,建议每个测试独立设置或在
afterEach还原
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











