首页 > 解决方案 > Vue2:当测试包含功能性子组件的组件时,如何从子组件发出事件?

问题描述

我尝试对包含b-button(bootstrap vue 按钮)的组件进行单元测试。

我需要发出一个“点击”事件来模拟对 b 按钮子组件的点击,因为我使用了 shallowMount,所以所有子组件都被模拟了,我不能.trigger('click')在它上面。此外,我无法访问那个孩子的 vm,因为 b-button 是一个没有实例的功能组件,所以childWrapper.vm.$emit('click')也不起作用。

用 shallowMount 测试我的组件的最佳选择是什么?

我尝试了什么:

  1. 使用 mount 而不是 shallowMount.trigger('click')就可以了
  2. 使用的 shallowMount 和 pass {stubs: {BButton}}b-button 将与实际实现一起模拟,并将作为第 1 部分工作
  3. 试过btnWrapper.trigger('click'), btnWrapper.vm.$emit('click'), btnWrapper.element.click(), 都没有奏效。
// TemplateComponent.vue
<template>
  <div class="row">
    <div class="col-12 p-2">
      <b-button @click="eatMe">Eat me</b-button>
    </div>
  </div>
</template>

<script>
  import bButton from 'bootstrap-vue/es/components/button/button';

  export default {
    name: "TemplateComponent",
    components: {
      bButton
    },
    methods: {
      eatMe() {
        this.$emit('click')
      }
    }
  }
</script>
// TemplateComponent.test.js
import {shallowMount} from '@vue/test-utils';

import TemplateComponent from './TemplateComponent.vue';

describe('TemplateComponent', () => {
  let wrapper, vm;

  beforeEach(() => {
    wrapper = shallowMount(TemplateComponent);
  });

  it('should trigger the eatMe twice', () => {
    wrapper.setMethods({
      eatMe: jest.fn()
    });
    const btn = wrapper.find('b-button-stub');
    btn.trigger('click'); // won't work
    btn.vm.$emit('click'); // won't work

    expect(vm.eatMe.mock.calls.length).toEqual(2);
  });
});

标签: vue.jsjestjsvue-test-utils

解决方案


使用常规按钮将其存根以捕获发出事件。

describe('TemplateComponent', () => {
  let wrapper, vm;

  beforeEach(() => {
shallowMount(TemplateComponent, {
  stubs: {
    'b-button': {
      template: `<button @click='$listeners.click'></button>`
    }
  }
});

 it('should trigger the eatMe twice', () => {
    wrapper.setMethods({
      eatMe: jest.fn()
    });
    const btn = wrapper.find('whatever');
    btn.trigger('click'); // will now work. as it's swapped with a generic button, still processing the event.


    expect(vm.eatMe.mock.calls.length).toEqual(2);
  });




推荐阅读