在Nuxt中如何Mock多个Ref(及通用Ref)?基于Vitest与Nuxt测试工具
在Nuxt+Vitest中测试组件内的多个Ref
前置准备
确保已安装@nuxt/test-utils和vitest,并在nuxt.config.ts中完成测试相关配置。
核心思路
组件内部定义的ref无需mock,挂载组件后可直接通过实例访问或DOM操作验证行为;依赖的useRoute则需在测试前进行mock。
完整测试示例
假设你的SideBar.vue结构如下:
<template> <div class="sidebar"> <button @click="isCollapsed = !isCollapsed">切换折叠</button> <div v-if="!isCollapsed" class="tokens">Tokens: {{ tokens }}</div> <div class="current-path">{{ path }}</div> </div> </template> <script setup> import { ref } from 'vue' import { useRoute } from 'vue-router' const isCollapsed = ref(false); const tokens = ref(0); const path = ref(useRoute().path); </script>
对应的测试文件SideBar.spec.ts写法如下:
import { describe, it, expect, vi } from 'vitest' import { mount, mockNuxtImport } from '@nuxt/test-utils/runtime' import SideBar from './SideBar.vue' describe('SideBar组件测试', () => { // Mock useRoute 返回预设路径 mockNuxtImport('useRoute', () => { return () => ({ path: '/dashboard' }) }) it('点击折叠按钮可切换isCollapsed状态', async () => { const wrapper = await mount(SideBar) // 初始状态验证 expect(wrapper.vm.isCollapsed).toBe(false) expect(wrapper.find('.tokens').exists()).toBe(true) // 模拟点击按钮 await wrapper.find('button').trigger('click') // 验证状态切换 expect(wrapper.vm.isCollapsed).toBe(true) expect(wrapper.find('.tokens').exists()).toBe(false) // 再次点击恢复状态 await wrapper.find('button').trigger('click') expect(wrapper.vm.isCollapsed).toBe(false) }) it('tokens值应正确显示在HTML中', async () => { const wrapper = await mount(SideBar) // 验证初始值显示 expect(wrapper.find('.tokens').text()).toContain('Tokens: 0') // 修改tokens值并等待DOM更新 wrapper.vm.tokens = 100 await wrapper.vm.$nextTick() expect(wrapper.find('.tokens').text()).toContain('Tokens: 100') }) it('路由路径应正确显示', async () => { const wrapper = await mount(SideBar) expect(wrapper.find('.current-path').text()).toBe('/dashboard') }) })
关键说明
- 访问组件内ref:
<script setup>中定义的ref会自动暴露在组件实例上,可通过wrapper.vm.xxx直接访问或修改。 - Mock路由:使用
mockNuxtImport拦截useRoute,返回预设的路由对象,确保组件获取到预期路径。 - DOM更新等待:修改ref值后,需调用
await wrapper.vm.$nextTick()等待Vue完成DOM更新,再执行断言。 - 事件模拟:用
trigger('click')模拟用户点击,需加await等待事件处理完成。
内容的提问来源于stack exchange,提问作者Leo Gall
相关产品推荐
相关产品推荐

