升级MUI v5后enzyme mount测试Drawer/Modal报scrollTop为空错误
问题根因
MUI v5 的 Drawer、Modal 组件默认开启了 Portal 特性,会将组件内部内容渲染到当前 DOM 树外的 body 节点下。enzyme 的 mount 方法默认仅将组件挂载到内部创建的独立 DOM 节点上,无法识别 Portal 导出的外部节点,导致过渡动画执行时获取 DOM 节点为 null,触发 scrollTop 访问报错。
单独测试 Fade 组件无异常是因为 Fade 本身没有使用 Portal 特性,所有节点都在 enzyme 的挂载树范围内。
可用解决方案
方案1:测试场景下禁用 Portal 特性
给 Drawer/Modal 组件添加disablePortal属性,强制内容渲染在当前组件 DOM 树内,无需修改其他逻辑即可解决报错,适合不需要验证 Portal 相关行为的测试场景:it('Test Drawer', () => { enzyme.mount(<Drawer open={true} disablePortal > <div>hello world</div> </Drawer>); })方案2:指定 mount 挂载的真实 DOM 节点
若测试需要保留 Portal 特性,可手动创建 DOM 节点挂载到 body 上,将 enzyme 的 mount 目标指定到该节点,测试结束后手动清理节点:it('Test Drawer', () => { // 创建挂载节点并加入body const mountContainer = document.createElement('div'); document.body.appendChild(mountContainer); // 挂载组件时指定attachTo const wrapper = enzyme.mount(<Drawer open={true}><div>hello world</div></Drawer>, { attachTo: mountContainer }); // 此处写测试断言逻辑 // 测试完成后清理 wrapper.unmount(); document.body.removeChild(mountContainer); })方案3:禁用过渡动画
若测试不需要验证过渡效果,可直接关闭 Drawer/Modal 的过渡逻辑,绕过过渡阶段的 DOM 访问逻辑:// 自定义无过渡组件 const NoTransition = ({ children }) => children; it('Test Drawer', () => { enzyme.mount(<Drawer open={true} TransitionComponent={NoTransition} > <div>hello world</div> </Drawer>); })
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

