Emi
Emi

Reputation: 173

How do I make my vue-unit-test trigger a click event on v-btn in Vuetify?

I am creating some unit test for my component, but the test keeps failing, since the button I'm testing keeps not getting triggerd by a click-event.

I've used the docs as a foundation for my test: https://vuetifyjs.com/sv-SE/getting-started/unit-testing/

I've also tried some of the suggestions mentioned here: https://forum.vuejs.org/t/how-to-trigger-an-onchange-event/11081/4

But it seems like I'm missing something, anyone who can help me out?

My test:

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)

    })

myComponent:

<template>

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

<template>

<script>
methods: {

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

Upvotes: 2

Views: 5630

Answers (1)

Hope this help, I changed your HTML a bit.

  • Firstly, I added a <div> and put <v-btn> inside it, this is very important.
  • Secondly, I declared a data prop called index which is initialized in 1.
  • Thirdly, I used data-testid="button" to identify it and find it during test.
<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>

Now, for the unit test.

The key is to use vm.$emit('click') instead of .trigger('click') since v-btn is a component of Vuetify. If you were using button tag, then you can use .trigger('click'). Also, I changed how jest finds this button.

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)
  })
})

Now, when you are doing a unit test, you should check inputs and outputs. In this case, your input is the click event and your output, is not your method been called, but the data modified or sent by this method. That's why I declared index to see if it changes when you click the button.

Anyway, if you want to check if your method was called, you can use this code instead

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)
  })
})

But you will receive the next error:

[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.

This is my first post btw

Upvotes: 8

Related Questions