Vue3组合式API中trigger('click')后组件方法未调用的测试问题
问题分析与解决方案
核心问题定位
你测试里点击的是<li>元素,但组件中@click="selectMeter(meter), newMeter()"的点击事件实际绑定在<a>标签上。直接触发<li>的点击不一定能正确触发子元素<a>的事件处理器,这是函数未被调用的主要原因。另外,测试中重新赋值的selectedMeter是测试作用域的变量,和组件内部使用的响应式状态(比如store里的selectedMeter)没有关联,会导致断言不符合预期。
修复步骤
1. 触发正确的点击目标
不要点击<li>,直接找到<li>下的<a>元素触发点击:
// 替换原有的li点击代码 await wrapper.findAll("li a").at(0).trigger("click");
2. 修正断言逻辑
测试里重新定义的selectedMeter和组件内部状态无关,直接断言store的状态变化即可:
// 移除测试作用域的selectedMeter赋值代码 // selectedMeter = ref({ meterId: "9090909090", zeusId: 9090 }); // 断言时直接检查store的selectedMeter expect(store.selectedMeter.meterId).toBe("123");
3. 优化监听方式(可选)
如果selectMeter内部调用了store的action,直接监听store的action会更可靠:
// 测试开头监听store的对应action(假设selectMeter调用了store.setSelectedMeter) const setSelectedMeterSpy = vi.spyOn(store, 'setSelectedMeter'); // 触发点击后断言 expect(setSelectedMeterSpy).toHaveBeenCalledWith(expect.objectContaining({ meterId: "123" }));
完整修复后的测试代码
it('calls selectMeter with correct meter when clicked', async () => { const store = useAuditStore(); const spy = vi.spyOn(wrapper.vm, 'selectMeter'); // 打开下拉框 await wrapper.find("button").trigger("click"); await flushPromises(); // 触发第一个<a>标签的点击 await wrapper.findAll("li a").at(0).trigger("click"); await flushPromises(); console.log(`Selected meter text: ${wrapper.findAll("li").at(0).text()}`) expect(spy).toHaveBeenCalledOnce(); expect(store.selectedMeter.meterId).toBe("123"); });
额外注意事项
- 触发点击后记得调用
await flushPromises(),确保Vue的响应式更新和异步操作完成。 - 不要在测试中重新赋值测试作用域的ref变量,组件使用的是自身响应式数据或store状态,两者不会同步。
内容的提问来源于stack exchange,提问作者Imalizard Dawg
相关产品推荐
相关产品推荐

