Vue Test Utils 2测试Vuetify v-checkbox报错:wrapper.setValue()不可用
问题描述
在Jest测试中尝试对Vuetify复选框调用setValue方法时遇到错误:wrapper.setValue() cannot be called on V-CHECKBOX。
使用技术栈:Vue 3、Vue Test Utils 2、Vuetify
测试代码
it('checks "Select All" when all items are selected', async () => { const checkboxes = wrapper.findAll('.enable-item-checkbox'); const checkboxA = wrapper.find('.checkboxA') const selectAllCheckbox = checkboxes.at(0) expect(selectAllCheckbox.attributes('checked')).toBeFalsy(); expect(checkboxA.attributes('checked')).toBe('false'); await checkboxA.setValue(true); expect(checkboxA.attributes('checked')).toBeTruthy(); expect(selectAllCheckbox.attributes('checked')).toBeTruthy(); });
Vuetify元素代码
<div class="mr-25" v-for="items in items" :key="provider" style="display: inline-block"> <v-checkbox :value="item" v-model="selectedItems" :checked="isSelected(items)" class="enable-item-checkbox" :class="{ [`${item}`]: true }" ></v-checkbox> </div>
已配置内容
- setup.js文件:
import Vue from 'vue'; import Vuetify from 'vuetify'; Vue.use(Vuetify); Vue.config.productionTip = false;
- package.json测试脚本:
"test": "jest --require ./src/tests/setup.js"
已尝试过的方法:使用mount而非shallowMount、setChecked、添加await wrapper.vm.$nextTick()、trigger('click')、trigger('change'),均未解决问题。
解决方案
1. 修正Vue 3的setup配置
你的setup.js是Vue 2的写法,Vue 3中需要调整为:
import { createApp } from 'vue'; import Vuetify from 'vuetify'; import 'vuetify/dist/vuetify.min.css'; const app = createApp({}); app.use(Vuetify);
2. 正确操作Vuetify复选框的方式
Vuetify的v-checkbox是封装组件,不能直接对组件实例调用setValue,需要操作内部的原生input元素:
方法一:触发原生input的change事件
找到v-checkbox内部的原生<input>元素,手动设置其checked属性并触发change事件:
it('checks "Select All" when all items are selected', async () => { const checkboxes = wrapper.findAll('.enable-item-checkbox'); const checkboxA = wrapper.find('.checkboxA'); const selectAllCheckbox = checkboxes.at(0); expect(selectAllCheckbox.attributes('checked')).toBeFalsy(); expect(checkboxA.attributes('checked')).toBe('false'); // 获取原生input元素 const checkboxAInput = checkboxA.find('input[type="checkbox"]'); // 设置checked属性 checkboxAInput.element.checked = true; // 触发change事件 await checkboxAInput.trigger('change'); // 等待Vue更新DOM await wrapper.vm.$nextTick(); expect(checkboxA.attributes('checked')).toBeTruthy(); expect(selectAllCheckbox.attributes('checked')).toBeTruthy(); });
方法二:直接修改组件的v-model绑定值
如果能直接访问组件的selectedItems数据,可以直接修改它并等待DOM更新:
it('checks "Select All" when all items are selected', async () => { const checkboxes = wrapper.findAll('.enable-item-checkbox'); const checkboxA = wrapper.find('.checkboxA'); const selectAllCheckbox = checkboxes.at(0); expect(selectAllCheckbox.attributes('checked')).toBeFalsy(); expect(checkboxA.attributes('checked')).toBe('false'); // 直接修改v-model绑定的数组 wrapper.vm.selectedItems.push('itemA'); // 替换为你的item实际值 await wrapper.vm.$nextTick(); expect(checkboxA.attributes('checked')).toBeTruthy(); expect(selectAllCheckbox.attributes('checked')).toBeTruthy(); });
3. 关键注意事项
- 避免同时使用
v-model和:checked,这会导致数据流向冲突,Vue 3中优先使用v-model控制复选框状态,isSelected方法可整合到v-model的逻辑中。 - 确保mount组件时正确初始化Vuetify实例:
import { mount } from '@vue/test-utils'; import Vuetify from 'vuetify'; import YourComponent from './YourComponent.vue'; const vuetify = new Vuetify(); describe('YourComponent', () => { let wrapper; beforeEach(() => { wrapper = mount(YourComponent, { global: { plugins: [vuetify] } }); }); // 测试用例... });
内容的提问来源于stack exchange,提问作者j leigh
相关产品推荐
相关产品推荐

