Reputation: 173
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
Reputation: 81
Hope this help, I changed your HTML a bit.
<div>
and put <v-btn>
inside it, this is very
important.index
which is
initialized in 1
.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