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

Vue3+Vitest测试:如何访问组件内函数及解决高度计算问题

解决Vue组件Vitest测试中的两个核心问题

一、解决clientHeight返回0的问题

测试环境(jsdom)不会自动计算元素布局,导致clientHeight默认返回0,可通过以下方式处理:

1. 手动模拟元素clientHeight

直接在测试中给目标元素的clientHeight赋值,模拟内容溢出场景:

test('模拟内容溢出时显示按钮', async () => {
  const wrapper = mount(MyComponent, {
    slots: {
      default: '<p>测试文本</p>'
    }
  })
  // 获取组件内的容器元素
  const container = wrapper.find('.content-container')
  // 模拟容器高度超过阈值
  container.element.clientHeight = 200 // 假设阈值为150
  // 调用组件内的检测逻辑
  await wrapper.vm.checkContentOverflow()
  await wrapper.vm.$nextTick()
  expect(wrapper.find('.show-more-btn').exists()).toBe(true)
})

2. 将组件挂载到真实DOM节点

通过attachTo选项把组件挂载到模拟的DOM节点,让jsdom计算真实布局:

test('挂载到DOM后检测高度', async () => {
  const div = document.createElement('div')
  document.body.appendChild(div)
  
  const wrapper = mount(MyComponent, {
    attachTo: div,
    slots: {
      // 传入足够长的文本触发溢出
      default: '<p>' + '重复文本'.repeat(30) + '</p>'
    }
  })
  
  await wrapper.vm.$nextTick()
  expect(wrapper.find('.show-more-btn').exists()).toBe(true)
  
  // 测试完成后清理
  wrapper.unmount()
  document.body.removeChild(div)
})

3. 提取检测逻辑单独测试

把高度检测逻辑抽成独立函数,直接测试函数逻辑而非依赖DOM:

// 组件内(<script setup>)
import { ref, onMounted, defineExpose } from 'vue'
const containerRef = ref(null)
const isButtonVisible = ref(false)
const HEIGHT_THRESHOLD = 150

const checkContentOverflow = () => {
  if (!containerRef.value) return
  isButtonVisible.value = containerRef.value.clientHeight > HEIGHT_THRESHOLD
}

onMounted(() => checkContentOverflow())
defineExpose({ checkContentOverflow, isButtonVisible })

测试时直接mock容器元素并调用函数:

test('检测溢出逻辑正确性', () => {
  const wrapper = mount(MyComponent)
  // 模拟容器高度超过阈值
  wrapper.vm.$refs.containerRef = { clientHeight: 200 }
  wrapper.vm.checkContentOverflow()
  expect(wrapper.vm.isButtonVisible).toBe(true)
})

二、访问<script setup>中的变量和函数

<script setup>内的变量、函数默认私有,需用defineExpose暴露给测试用例:

// 组件内(<script setup>)
import { ref, defineExpose } from 'vue'

const isButtonVisible = ref(false)
const makeButtonVisible = () => {
  isButtonVisible.value = true
}

// 暴露需要测试的内容
defineExpose({
  isButtonVisible,
  makeButtonVisible
})

之后在测试中即可正常访问,注意修改后需等待DOM更新:

test('手动控制按钮显示', async () => {
  const wrapper = mount(MyComponent)
  // 调用暴露的函数
  await wrapper.vm.makeButtonVisible()
  await wrapper.vm.$nextTick()
  expect(wrapper.find('.show-more-btn').exists()).toBe(true)

  // 或者直接修改ref变量
  wrapper.vm.isButtonVisible = true
  await wrapper.vm.$nextTick()
  expect(wrapper.find('.show-more-btn').exists()).toBe(true)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 22:20:06