With apps getting more complex than ever, it’s important to test them automatically. We can do this with unit tests, and then we don’t have to test everything by hand.
In this article, we’ll look at how to test Vue 3 apps by writing a simple app and testing it.
Event Handling
We can test event handling in our Vue 3 components easily with Vue Test Utils.
For example, we can write:
import { mount } from '@vue/test-utils'
const Counter = {
template: '<button @click="handleClick">Increment</button>',
data() {
return {
count: 0
}
},
methods: {
handleClick() {
this.count += 1
this.$emit('increment', this.count)
}
}
}
test('emits increment event when button is clicked', () => {
const wrapper = mount(Counter)
wrapper.find('button').trigger('click')
expect(wrapper.emitted()).toHaveProperty('increment')
})
We have the Counter
component that has a button that runs the handleclick
method when we click it.
The handleClick
method emits the increment
event.
In the test, we mount the Counter
component.
Then we get the button with find
and call trigger
with the click
method.
And then we check if the increment
event is emitted with the wrapper.emitted
method.
The returned object has the event names as the key.
We can do other checks in our tests with regard to events.
For instance, we can write:
import { mount } from '@vue/test-utils'
const Counter = {
template: '<button @click="handleClick">Increment</button>',
data() {
return {
count: 0
}
},
methods: {
handleClick() {
this.count += 1
this.$emit('increment', this.count)
}
}
}
test('emits increment event when button is clicked', () => {
const wrapper = mount(Counter)
wrapper.find('button').trigger('click')
expect(wrapper.emitted()).toHaveProperty('increment')
const incrementEvent = wrapper.emitted('increment')
expect(incrementEvent).toHaveLength(1)
expect(incrementEvent[0]).toEqual([1])
})
We get the increment event object with:
const incrementEvent = wrapper.emitted('increment')
Then we check how many time it’s emitted with:
expect(incrementEvent).toHaveLength(1)
And we check the value that it’s emitted with, which the 2nd argument of this.$emit
with:
expect(incrementEvent[0]).toEqual([1])
Asserting Complex Events
We can test more complex event objects.
For example, we can write:
import { mount } from '@vue/test-utils'
const Counter = {
template: '<button @click="handleClick">Increment</button>',
data() {
return {
count: 0
}
},
methods: {
handleClick() {
this.count += 1
this.$emit('increment', {
count: this.count,
isEven: this.count % 2 === 0
})
}
}
}
test('emits increment event when button is clicked', () => {
const wrapper = mount(Counter)
wrapper.find('button').trigger('click')
wrapper.find('button').trigger('click')
expect(wrapper.emitted('increment')).toHaveLength(2)
const [event1, event2] = wrapper.emitted('increment')
expect(event1).toEqual([
{
count: 1,
isEven: false
}
])
expect(event2).toEqual([
{
count: 2,
isEven: true
}
])
})
We trigger the click
event on the button twice.
Then we check the number of times the increment
event is emitted with:
expect(wrapper.emitted('increment')).toHaveLength(2)
Then we get the event objects that are emitted with:
const [event1, event2] = wrapper.emitted('increment')
Then we check the event object that we emitted with the event with:
expect(event1).toEqual([{
count: 1,
isEven: false
}])
expect(event2).toEqual([{
count: 2,
isEven: true
}])
Conclusion
We can test event emissions with Vue 3 and Vue Test Utils.