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
相关产品推荐
相关产品推荐

