Vue单元测试:切换script setup后wrapper.vm为空,defineExpose无效
解决方案
核心问题
你当前的wrapper指向的是包裹了Suspense的TestComponent实例,而非目标SharepriceGraph组件,再加上<script setup>默认的闭包特性,导致直接通过wrapper.vm访问不到目标组件的内部属性和计算属性。以下是具体解决步骤:
1. 精准获取目标组件实例
通过测试工具的findComponent方法定位到SharepriceGraph子组件,再访问它的vm对象:
it('Check that the axis spacing options are set up correctly for less than 20 shareprice results', async () => { global.innerWidth = 1440 global.dispatchEvent(new Event('resize')) await nextTick() // 获取SharepriceGraph组件的实例wrapper const graphWrapper = wrapper.findComponent(SharepriceGraph) // 访问目标计算属性 expect(graphWrapper.vm.hAxisLabelSpacing).toBe(0) })
2. 确保defineExpose正确导出属性
在SharepriceGraph的<script setup>中,必须显式导出需要在测试中访问的变量和计算属性:
<script setup> import { ref, computed } from 'vue' const isScreenLg = ref(false) const hAxisLabelSpacing = computed(() => isScreenLg.value ? 0 : 4) // 导出测试所需的属性 defineExpose({ isScreenLg, hAxisLabelSpacing }) </script>
3. 简化测试组件挂载逻辑
如果只是为了解决异步组件的Suspense警告,无需额外封装TestComponent,可以直接在挂载时处理:
import { mount, h } from '@vue/test-utils' it('Check axis spacing configuration', async () => { // 异步挂载并处理Suspense const wrapper = await mount(() => h(Suspense, null, { default: h(SharepriceGraph) })) const graphWrapper = wrapper.findComponent(SharepriceGraph) // 后续测试逻辑... })
4. 直接模拟状态替代resize事件
如果测试不想依赖浏览器resize事件,可以直接修改导出的响应式变量:
it('Verify axis spacing values', async () => { const graphWrapper = wrapper.findComponent(SharepriceGraph) // 直接设置isScreenLg状态 graphWrapper.vm.isScreenLg = true await nextTick() expect(graphWrapper.vm.hAxisLabelSpacing).toBe(0) graphWrapper.vm.isScreenLg = false await nextTick() expect(graphWrapper.vm.hAxisLabelSpacing).toBe(4) })
内容的提问来源于stack exchange,提问作者KatieAdamsDev
相关产品推荐
相关产品推荐

