You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 02:17:18