vue组件测试核心是验证props输入下的emits输出、dom渲染和状态变化;vitest因启动快、与vite集成深、兼容jest成为vue3首选,需安装vitest、@vue/test-utils、happy-dom,配置environment为happy-dom,并通过mount断言props响应、emit事件及交互链。

Vue.js 组件测试的核心,是验证它在给定 props 输入 下是否产生预期的 emits 输出、DOM 渲染和内部状态变化。Vitest 因启动快、与 Vite 深度集成、API 兼容 Jest,已成为 Vue3 项目事实上的测试首选。
环境准备:三步到位
确保项目已基于 Vite 构建(如通过 npm create vue@latest 创建)。接着执行:
- 安装依赖:
pnpm add -D vitest @vue/test-utils happy-dom(推荐happy-dom而非jsdom,对 Vue 组件 DOM 测试更快更轻) - 在
vite.config.ts中添加 test 配置:test: { environment: 'happy-dom', globals: true } - 在
package.json加入脚本:"test": "vitest"
Props 测试:不止传进去,更要“反应对”
不能只检查 props 是否被接收,而要看组件是否按逻辑响应。例如一个带 disabled prop 的按钮:
- 挂载时传入:
const wrapper = mount(Button, { props: { disabled: true } }) - 断言 DOM 属性:
expect(wrapper.find('button').attributes('disabled')).toBeDefined() - 检查样式类或内部 ref 变化:
expect(wrapper.vm.isDisabled).toBe(true) - 验证行为抑制:点击后
expect(wrapper.emitted('click')).toBeUndefined()
Emit 测试:校验事件名、次数与参数
emit 是组件对外暴露契约的关键,必须精确断言。比如 modelValue 改变后触发 update:modelValue:
- 挂载并模拟交互:
const wrapper = mount(Switch, { props: { modelValue: false } }); wrapper.find('.switch').trigger('click') - 断言事件发生:
expect(wrapper.emitted('update:modelValue')).toHaveLength(1) - 断言参数正确:
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]) - 异步场景需等待更新:
await nextTick(); expect(...)
真实交互链:Props → 用户操作 → Emit → 状态联动
复杂组件常存在多层响应。例如输入框组件接收 modelValue,用户输入后应 emit 更新值,并同步影响内部 inputRef.value:
- 初始挂载:
mount(Input, { props: { modelValue: 'old' } }) - 触发输入:
wrapper.find('input').setValue('new') - 断言 emit:
expect(wrapper.emitted('update:modelValue')![0]).toEqual(['new']) - 断言 DOM 同步:
expect(wrapper.find('input').element.value).toBe('new')
不复杂但容易忽略:每次 mount 创建的是全新实例,emitted() 只记录该次生命周期;跨测试用例不能共享状态,也不可复用 wrapper。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











