Vue Test Utils使用findComponent查找子组件内元素报setValue空DOMWrapper错误
问题原因&解决方案
核心报错原因
你调用findComponent拿到State组件实例后,多余调用.find('select')是在State组件的根元素内部查找select节点,但State组件的根元素本身就是select,所以查找不到任何元素,返回空DOMWrapper触发报错。
其他存在的问题
- 事件断言逻辑错误:
Create组件的create事件只抛出1个包含name和state属性的对象参数,你写的断言是按抛出两个独立参数逻辑写的,会触发断言失败。 - 冗余的DOM挂载逻辑:手动创建div挂载的操作没有必要,Vue Test Utils默认会将组件挂载到内存中的DOM节点,测试结束自动销毁。
修正后的测试代码
import { mount } from '@vue/test-utils'; import Create from './Create.vue'; describe('it tests Create component', () => { test('it emits create event and resets the form when form is valid and create button is clicked', async () => { const expectedNameValue = 'TODO_NAME'; const expectedStateValue = 'Pending'; const wrapper = mount(Create); // 用更精准的选择器查找输入框,避免后续加其他输入框时出错 await wrapper.find(`input[name="name"]`).setValue(expectedNameValue); // 直接给State组件Wrapper调用setValue即可,它的根元素就是select await wrapper.findComponent({ ref: 'state-component' }).setValue(expectedStateValue); await wrapper.find(`form`).trigger('submit'); expect(wrapper.emitted().create).toBeTruthy(); // 修正断言,匹配emit抛出的对象结构 expect(wrapper.emitted().create[0][0]).toEqual({ name: expectedNameValue, state: expectedStateValue }); expect(wrapper.find(`input[name='name']`).element.value).toEqual(''); expect(wrapper.find(`select[name='state']`).element.value).toEqual('Pending'); }); });
优化建议
- 元素查找优先用
data-testid属性:给需要测试的元素加data-testid自定义属性,比如<input data-testid="todo-name-input" />,测试时用wrapper.find('[data-testid="todo-name-input"]')查找,标签、类名变更不会影响测试稳定性。 State组件可以给state设置默认值Pending,避免无todo属性为空时选中逻辑不明确的问题:
data() { return { name: "", state: "Pending", // 新增默认值 states: ["Pending", "In Progress", "Done"], }; }
- 测试用例尽量拆分,把表单赋值、提交事件触发、表单重置三个逻辑分成三个独立测试用例,报错时更容易定位问题。
State组件created钩子中return true没有实际意义,可以直接删除。
内容的提问来源于stack exchange,提问作者developeryarkin
相关产品推荐
相关产品推荐

