关于 vue-test-utils-skilld
vue-test-utils-skilld 介绍 Vue 3 的 `@vue/test-utils`,供使用 Vitest、Jest 等测试运行器的开发者挂载组件并检查行为。它支持完整挂载、浅挂载和服务端字符串渲染,并提供包装器查询及异步更新辅助工具。
主要功能
- 01完整挂载与浅挂载组件
- 02查询组件和 DOM 包装器
- 03触发事件并设置属性
- 04等待异步任务与 Vue 更新
- 05执行服务端字符串渲染
- 06通过测试钩子自动卸载
适用场景
- 01测试点击后组件状态的变化
- 02验证属性、表单值与事件
- 03检查可选元素是否存在
- 04测试依赖异步请求的界面
- 05为组件编写服务端渲染测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ skilld-dev/ vue-ecosystem-skills --skill vue-test-utils-skilld安装后在 Claude Code 中输入/vue-test-utils-skilld确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/migration-v2.mdmounting-options.mdrecipes.mdwrapper-api.md详细介绍
@vue/test-utils 2.5.1(Vue 3)
准备好的源代码:input/source,版本为 2.5.1(package.json:3)。
需要 Vue 3.x 和 @vue/compiler-dom 3.x 作为对等依赖;@vue/server-renderer 3.x 是可选对等依赖,仅在使用 renderToString 时需要(package.json:73-81)。
与测试运行器无关(Vitest、Jest 等)。需要类浏览器的 DOM 环境(jsdom 或 happy-dom)。
安装:npm install @vue/test-utils --save-dev
快速开始
import { mount } from '@vue/test-utils'
import Counter from './Counter.vue'
test('increments', async () => {
const wrapper = mount(Counter, { props: { start: 1 } })
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('2')
})
公共 API 概览
从 dist/src/index.d.ts:13 导出:
| 导出项 | 类型 | 用途 |
|---|---|---|
mount | 函数 | 挂载组件,返回 VueWrapper(dist/src/mount.d.ts:17) |
shallowMount | 函数 | 与 mount 相同,但会为所有子组件创建存根(dist/src/mount.d.ts:22) |
renderToString | 函数 | 将组件渲染为 SSR 字符串,返回 Promise<string>(dist/src/renderToString.d.ts:4) |
flushPromises | 函数 | 等待尚未完成的非 Vue Promise(模拟的 API 调用、计时器)(dist/src/utils/flushPromises.d.ts:1) |
enableAutoUnmount(hook) | 函数 | 通过测试钩子卸载所有包装器(dist/src/utils/autoUnmount.d.ts:4) |
disableAutoUnmount | 函数 | 停止自动卸载(dist/src/utils/autoUnmount.d.ts:3) |
VueWrapper | 类 | 已挂载组件实例的包装器(dist/src/vueWrapper.d.ts:5) |
DOMWrapper | 类 | DOM 元素的包装器;new DOMWrapper(document.body)(dist/src/domWrapper.d.ts:4) |
RouterLinkStub | 组件 | <router-link> 的存根(dist/src/components/RouterLinkStub.d.ts:1) |
config | 对象 | 共享的默认挂载选项和包装器插件(dist/src/config.d.ts:32) |
createWrapperError | 函数 | 内部使用;生成 find 未找到结果时返回的错误包装器 |
核心规则
- 对所有返回 Promise 的方法使用
await:trigger、setValue、setProps、setData、renderToString、flushPromises。不使用await时,断言会在 DOM 更新之前运行。 - 元素必须存在时使用
get()/getComponent();未找到时它们会抛出错误。仅在元素不存在也属于有效结果时使用find()/findComponent();未找到时它们会返回一个错误包装器,其exists()为false。 find()仅接受 CSS 选择器。要查找子组件,请使用findComponent(Component)、findComponent({ name: 'Foo' })、findComponent({ ref: 'foo' })或 CSS 选择器。- 在测试设置中注册一次
enableAutoUnmount(afterEach),以防止测试之间状态泄漏。 - 对 Vue 不会跟踪的 Promise(模拟的 HTTP 客户端、
setTimeout)使用flushPromises()。 wrapper.vm只能可靠地公开组件所公开的内容:Options API 状态、defineExpose()绑定(自 2.5.0 起,PR #2927),或setup()返回值。
import { enableAutoUnmount } from '@vue/test-utils'
import { afterEach } from 'vitest'
enableAutoUnmount(afterEach)
版本说明:2.4.10 -> 2.5.1
- BREAKING(2.5.0):移除了对类组件的支持。请使用
defineComponent、选项对象或<script setup>单文件组件定义 Vue 组件并进行挂载。https://github.com/vuejs/test-utils/releases/tag/v2.5.0 - 修复(2.5.0):子组件卸载时会清除其
emitted()历史记录。请在卸载前断言事件。https://github.com/vuejs/test-utils/pull/2898 - 修复(2.5.0):
defineExpose绑定可通过findComponent(...).vm访问。https://github.com/vuejs/test-utils/pull/2927 - 修复(2.4.11):对于混用
setup()和data()的组件,setData()可正常工作。https://github.com/vuejs/test-utils/releases/tag/v2.4.11 - 修复(2.4.11):
trigger('keydown')会设置符合规范的event.code。https://github.com/vuejs/test-utils/pull/2850 - 类型(2.4.11):导出了
GlobalMountOptions。https://github.com/vuejs/test-utils/pull/2851
仍然适用的早期 v2 里程碑
- 2.3.0 中新增了用于 SSR 测试的
renderToString。 https://github.com/vuejs/test-utils/releases/tag/v2.3.0 - 2.2.0 中新增了
html({ raw: true })、指令桩(vName: true)以及用于多选的数组型setValue。 https://github.com/vuejs/test-utils/releases/tag/v2.2.0 enableAutoUnmount/disableAutoUnmount取代了 v1 的enableAutoDestroy。 https://github.com/vuejs/test-utils/releases/tag/v2.0.0-rc.16propsData仍然可用,但已弃用;请使用props(dist/src/types.d.ts:33-35)。stubs接受一个记录({ Foo: true })或名称数组(['Foo'])(dist/src/types.d.ts:80)。
从 v1(Vue 2)迁移
完整表格:迁移参考,官方指南 https://test-utils.vuejs.org/migration/
propsData->props;已移除createLocalVue-> 使用global.plugins/global.mixinsmocks、stubs、provide、directives移至global下destroy()->unmount();findAll().at(i)->findAll()[i](返回数组)- 已移除
createWrapper()-> 使用new DOMWrapper(el) - 已移除
setChecked/setSelected-> 合并至setValue find()不再按名称查找组件;请使用findComponentshallowMount不再渲染桩组件的默认插槽内容;通过config.global.renderStubDefaultSlot = true恢复- 已移除:
is、isEmpty、isVueInstance、name、setMethods、contains、scopedSlots(已合并至slots)
最佳实践
- 优先使用
mount和有针对性的global.stubs,而不是shallowMount。浅层测试断言的是结构,而非行为;桩化的子组件会隐藏真实交互。 https://test-utils.vuejs.org/guide/advanced/stubs-shallow-mount - 如果广泛使用桩,请设置
config.global.renderStubDefaultSlot = true,以便仍能渲染桩组件的默认插槽内容(dist/src/types.d.ts:125-131)。 - 使用
vName键桩化指令:global.stubs: { vTooltip: true },或传入替代指令对象。 <transition>和<transition-group>默认会被桩化(dist/src/types.d.ts:120-124);也支持自定义过渡桩。- 通过
global.provide传入 inject 值,与生产环境中的注入方式保持一致。对于类型化注入键,请包装键:provide: { [injectionKey as symbol]: value }。 - 通过挂载最简宿主组件来测试组合式函数,并从
wrapper.vm读取状态。 - 挂载带有
async setup()的组件之前,先将其包裹在<Suspense>宿主中。 - 对于
<Teleport>,可以将其桩化(global.stubs: { teleport: true }),也可以在beforeEach中创建目标元素,并使用document.querySelector查询。 https://test-utils.vuejs.org/guide/advanced/teleport - 在不安装路由器的情况下测试
<router-link>周边行为时,请使用RouterLinkStub:global.stubs: { 'router-link': RouterLinkStub }。
参考
- 挂载选项和配置:每个
mount/shallowMount/renderToString选项、global.*以及config对象。 - Wrapper API:每个
VueWrapper/DOMWrapper方法及其签名。 - v1 -> v2 迁移:完整的选项和方法映射,以及 2.5.x 变更。
- 测试示例:表单、
v-model、触发事件、路由、Vuex/Pinia、Suspense、Teleport、SSR。
评论
支持 Markdown