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

升级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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 11:48:03