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

如何使用react-test-renderer测试Chakra-ui的modal对话框?

问题原因
  • Chakra UI 的 Modal 组件默认通过 Portal 机制将内容挂载到 document.body 节点,不在你传入 create 方法的组件树范围内,react-test-renderer 不会默认捕获根组件外的 Portal 内容,导致快照为空。
  • Modal 默认启用了淡入过渡动画,动画执行期间内容会被设置为隐藏状态,即使能捕获到 Portal 内容,动画未完成时生成的快照也会是空的。
解决方案

方案1(最简便):禁用Portal和动画

直接给 Modal 组件添加 disablePortal 和 motionPreset="none" 属性,让 Modal 直接渲染在当前组件树内,同时跳过动画逻辑,内容会直接处于可见状态:

expect(
  create(
    <PortalManager>
      <Modal 
        isOpen={true} 
        onClose={jest.fn()}
        disablePortal
        motionPreset="none"
      >
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Modal Title</ModalHeader>
          <ModalCloseButton />
          <ModalBody>Modal body</ModalBody>
          <ModalFooter>Modal footer</ModalFooter>
        </ModalContent>
      </Modal>
    </PortalManager>,
  ).toJSON(),
).toMatchSnapshot();

方案2:保留Portal特性的测试写法

如果你需要保留Portal的挂载逻辑验证,可以直接从document.body中读取Modal渲染的内容生成快照:

import { render } from '@testing-library/react'

test('modal 快照测试', () => {
  render(
    <PortalManager>
      <Modal 
        isOpen={true} 
        onClose={jest.fn()}
        motionPreset="none"
      >
        <ModalOverlay />
        <ModalContent>
          <ModalHeader>Modal Title</ModalHeader>
          <ModalCloseButton />
          <ModalBody>Modal body</ModalBody>
          <ModalFooter>Modal footer</ModalFooter>
        </ModalContent>
      </Modal>
    </PortalManager>
  )
  // 直接捕获body下的Modal容器内容生成快照
  expect(document.body.firstChild).toMatchSnapshot()
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:54:03