首页 > 解决方案 > 如何让我的 vue-unit-test 在 Vuetify 中触发 v-btn 上的点击事件?

问题描述

我正在为我的组件创建一些单元测试,但测试一直失败,因为我正在测试的按钮一直没有被点击事件触发。

我使用文档作为测试的基础:https ://vuetifyjs.com/sv-SE/getting-started/unit-testing/

我也尝试了这里提到的一些建议:https ://forum.vuejs.org/t/how-to-trigger-an-onchange-event/11081/4

但似乎我错过了一些东西,有人可以帮助我吗?

我的测试:

test('If you can click on the Test button', () => {
        const wrapper = shallowMount(myComponent, {
            localVue,
            vuetify,

        });

        const event = jest.fn();
        const button = wrapper.find({name: 'v-btn'})

        expect(button.exists()).toBe(true) //this works

         wrapper.vm.$on('v-btn:clicked', event)

        expect(event).toHaveBeenCalledTimes(0)

         button.trigger('click')

         expect(event).toHaveBeenCalledTimes(1)

    })

我的组件:

<template>

<v-btn class="primary-text" @click.native="methodForTesting($event)">Test</v-btn>

<template>

<script>
methods: {

methodForTesting(){
  console.log('button clicked!')
}
</script>

标签: jestjsvuetify.jsvue-test-utils

解决方案


希望对您有所帮助,我稍微更改了您的 HTML。

  • 首先,我添加了一个<div>并放入<v-btn>其中,这非常重要。
  • 其次,我声明了一个名为的数据道具index,它在1.
  • 第三,我曾经data-testid="button"在测试时识别它并找到它。
<template>
  <div>
    <v-btn data-testid="button" class="primary-text" @click="methodForTesting">Test</v-btn>
  </div>
</template>

<script>
export default {
  data() {
    return {
      index: 1
    };
  },
  methods: {
    methodForTesting() {
      this.index++;
    }
  }
};
</script>

现在,进行单元测试。

关键是要使用vm.$emit('click')而不是.trigger('click')因为v-btn是Vuetify的一个组件。如果您使用的是button标签,那么您可以使用.trigger('click'). 另外,我更改了 jest 找到此按钮的方式。

import Vuetify from 'vuetify'

// Utilities
import { mount, createLocalVue } from '@vue/test-utils'

// Components
import Test from '@/views/Test.vue';

// VARIABLES INITIALIZATION //
const vuetify = new Vuetify()
const localVue = createLocalVue()

// TESTING SECTION //
describe('Testing v-btn component', () => {
  it('should trigger methodForTesting', async () => {
    const wrapper = mount(Test, {
      localVue,
      vuetify,
    })
    const button = wrapper.find('[data-testid="button"]')

    expect(button.exists()).toBe(true)
    expect(wrapper.vm.$data.index).toBe(1)
    button.vm.$emit('click')
    await wrapper.vm.$nextTick()
    expect(wrapper.vm.$data.index).toBe(2)
  })
})

现在,当您进行单元测试时,您应该检查输入和输出。在这种情况下,您的输入是点击事件,而您的输出,不是您的方法被调用,而是该方法修改或发送的数据。这就是为什么我声明index当你点击按钮时它是否会改变。

无论如何,如果您想检查您的方法是否被调用,您可以使用此代码

describe('Testing v-btn component', () => {
  it('should trigger methodForTesting', async () => {
    const methodForTesting = jest.fn()
    const wrapper = mount(Test, {
      localVue,
      vuetify,
      methods: {
        methodForTesting
      }
    })
    const button = wrapper.find('[data-testid="button"]')

    expect(button.exists()).toBe(true)
    expect(methodForTesting).toHaveBeenCalledTimes(0)
    button.vm.$emit('click')
    await wrapper.vm.$nextTick()
    expect(methodForTesting).toHaveBeenCalledTimes(1)
  })
})

但是你会收到下一个错误:

[vue-test-utils]: overwriting methods via the `methods` property is deprecated and will be removed in the next major version. There is no clear migration path for the `methods` property - Vue does not support arbitrarily 
replacement of methods, nor should VTU. To stub a complex method extract it from the component and test it in isolation. Otherwise, the suggestion is to rethink those tests.

这是我的第一篇文章顺便说一句


推荐阅读