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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:30:54