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

Jest+Enzyme测试含useRef的Modal组件报style为null错误如何解决

错误原因

  1. Modal组件的useEffect逻辑存在漏洞:当isOpen为true且headerRef.current存在时,代码会直接读取selectedElement.style,但没有提前判断selectedElement是否为空。
  2. 你的测试场景刚好触发了报错条件:
    • ExampleModal中Modal组件的showModal初始值为true,isOpen默认处于打开状态
    • 你传入的自定义header是ModalHeader组件,它会将你传入的headerRef挂载到内部的h5元素上,因此headerRef.current不为空,触发后续逻辑
    • Modal组件的最外层DOM元素没有绑定你传入的id属性,导致document.querySelector(#${id})返回null,调用null.style直接抛出类型错误
  3. 当你把header替换为简单的<>{HEADER}</>时,这个header节点没有绑定headerRef,因此headerRef.current始终为null,不会触发后续读取selectedElement的逻辑,所以测试不会报错。

解决方案

方案1:修复Modal组件源码(推荐)

首先给Modal组件的最外层容器加上id={id}属性,确保选择器可以匹配到对应DOM元素;其次在访问selectedElement属性前增加非空判断,避免空值报错,修改useEffect逻辑如下:

useEffect(() => {
  const selectorId = `#${id}`
  const selectedElement: HTMLElement = document.querySelector(selectorId)
  // 增加selectedElement非空判断
  if (isOpen && headerRef.current && selectedElement) {
    headerRef.current.focus()
    selectedElement.style.right = '0px'
    document.body.style.overflow = 'hidden'
    setPostAnimationState(true)
  }

  const existElement = document.querySelector(selectorId)
  if (!isOpen && existElement) {
    document.body.style.overflow = 'auto'
    existElement.style.right = '-768px'
    setTimeout(() => {
      setPostAnimationState(false)
    }, 400)
  }
}, [isOpen, headerRef, id])

方案2:调整测试用例(无法修改组件源码时使用)

可任选一种方式:

  • 给ExampleModal的Modal组件传入正确的id,确保测试环境下选择器可以匹配到DOM节点
  • 测试时默认设置showModal初始值为false,避开首次渲染就触发打开逻辑,单独编写用例测试打开状态
  • Mockdocument.querySelector方法,让它返回一个带style属性的空对象,避免测试报错:
beforeEach(() => {
  jest.spyOn(document, 'querySelector').mockReturnValue({
    style: {}
  })
})
afterEach(() => {
  jest.restoreAllMocks()
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.14 22:15:04