在Vue组件单元测试中如何验证自定义事件触发次数?

婷婷 阅读 18

我在测试一个带计数功能的按钮组件时,发现用Vue Test Utils的$emit无法正确验证事件触发次数。组件点击后会连续触发两次自定义事件,但测试总是显示调用次数为0:


// CounterButton.vue
export default {
  methods: {
    handleClick() {
      this.$emit('increment');
      this.$nextTick(() => this.$emit('increment'));
    }
  }
}

测试代码这样写的:


import { mount } from '@vue/test-utils';
describe('CounterButton', () => {
  it('should emit increment twice', () => {
    const wrapper = mount(CounterButton);
    const spy = jest.spyOn(wrapper.vm, '$emit');
    wrapper.find('button').trigger('click');
    expect(spy.mock.calls.length).toBe(2); // 期望2次实际0次
  });
});

尝试过用wrapper.emitted(‘increment’)也返回空对象,是不是$nextTick里的emit需要特别处理?或者spy的使用方式有问题?

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
Good“瑞芳
问题出在你监听的时机不对,$emit 的 spy 没法正确捕获 $nextTick 里的调用。直接这样改:


import { mount } from '@vue/test-utils';
describe('CounterButton', () => {
it('should emit increment twice', async () => {
const wrapper = mount(CounterButton);
await wrapper.find('button').trigger('click');
await wrapper.vm.$nextTick(); // 等待 $nextTick 完成
expect(wrapper.emitted('increment').length).toBe(2); // 直接验证事件触发次数
});
});


别用 spy 去监听 $emit,用 wrapper.emitted() 更靠谱,记得加上 async/await$nextTick 执行完。
点赞 4
2026-02-14 15:03