Vue 3 Vitest:BaseInput组件v-model的emit触发测试问题
问题:BaseInput组件v-model测试中emit事件未触发?
我正尝试为带有v-model属性的BaseInput组件编写测试,期望组件在输入变化时触发emit事件。但在Vitest框架中更新输入后,似乎没有触发emit。
组件代码
<template> <label v-if="label">{{ label }}</label> <input v-bind="$attrs" :value="modelValue" :placeholder="label" @input="$emit('update:modelValue', $event.target.value)" class="field" /> </template> <script> export default { props: { label: { type: String, default: "", }, modelValue: { type: [String, Number], default: "", }, }, }; </script>
测试代码
import { describe, it, expect, beforeEach } from "vitest"; import { mount } from "@vue/test-utils"; import BaseInput from "@/components/base/BaseInput.vue"; describe("BaseInput", () => { let wrapper beforeEach(() => { wrapper = mount(BaseInput, { propsData: { label: 'Test Label', modelValue: 'Test Value' } }) }) it('emits input value when changed', async () => { // Assert input value gets the new value await wrapper.find('input').setValue('New Test Value') expect(wrapper.find('input').element.value).toBe('New Test Value') // Assert input event is emitted await wrapper.vm.$nextTick() expect(wrapper.emitted().input).toBeTruthy() //this fails }) });
测试结果:设置输入值后,组件未触发任何emit事件。
请问如何设置输入,以验证组件能正确触发输入值变化的emit事件?
解决方案
问题核心是测试时检查的事件名称错误:你的组件在输入变化时触发的是update:modelValue事件(Vue 3中v-model的标准绑定事件),但测试代码里却在断言input事件是否存在,这才导致测试失败。
修正后的测试代码如下:
import { describe, it, expect, beforeEach } from "vitest"; import { mount } from "@vue/test-utils"; import BaseInput from "@/components/base/BaseInput.vue"; describe("BaseInput", () => { let wrapper beforeEach(() => { wrapper = mount(BaseInput, { props: { // Vue Test Utils 4+推荐用props代替propsData label: 'Test Label', modelValue: 'Test Value' } }) }) it('emits update:modelValue with new value when input changes', async () => { const input = wrapper.find('input') await input.setValue('New Test Value') // 验证输入框值更新正确 expect(input.element.value).toBe('New Test Value') // 验证update:modelValue事件已触发 const emitEvent = wrapper.emitted()['update:modelValue'] expect(emitEvent).toBeTruthy() // 验证事件携带的参数正确 expect(emitEvent[0][0]).toBe('New Test Value') }) });
额外说明:
- Vue Test Utils 4及以上版本推荐使用
props选项代替propsData,测试代码已做对应调整 setValue方法本身会触发input事件并更新DOM,无需额外调用$nextTick(除非存在异步更新逻辑)- 除了验证事件是否触发,还需验证事件传递的参数与输入值一致,让测试更严谨
内容的提问来源于stack exchange,提问作者Spike
相关产品推荐
相关产品推荐

