How to Use Vue Test Utils for Vue Component Testing
Use
vue-test-utils by importing mount to create a wrapper around your Vue component. Then, interact with the wrapper to check rendered output or trigger events for testing component behavior.Syntax
The main function is mount, which creates a wrapper around a Vue component for testing. You import your component and pass it to mount. The wrapper lets you access the DOM, find elements, and simulate user actions.
Example parts:
import { mount } from '@vue/test-utils': imports the mount function.const wrapper = mount(Component): mounts the component and returns a wrapper.wrapper.text(): gets the text content inside the component.wrapper.find('selector'): finds an element inside the component.wrapper.trigger('event'): simulates an event like click.
javascript
import { mount } from '@vue/test-utils' import MyComponent from './MyComponent.vue' const wrapper = mount(MyComponent) console.log(wrapper.text())
Output
Rendered text content of MyComponent
Example
This example shows how to mount a simple Vue component, check its text, and simulate a button click that changes the text.
javascript
import { mount } from '@vue/test-utils' import { defineComponent, ref } from 'vue' const Counter = defineComponent({ setup() { const count = ref(0) const increment = () => count.value++ return { count, increment } }, template: `<div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> </div>` }) const wrapper = mount(Counter) console.log(wrapper.text()) // "Count: 0" const button = wrapper.find('button') button.trigger('click') console.log(wrapper.text()) // "Count: 1"
Output
Count: 0
Count: 1
Common Pitfalls
Common mistakes include:
- Not waiting for Vue's DOM updates after events, which can cause tests to check stale content.
- Using
shallowMountwhen you need full child component rendering or vice versa. - Forgetting to import
@vue/test-utilsor the component correctly. - Triggering events on elements that don't exist or are not found.
Always use await wrapper.vm.$nextTick() after triggering events if you check updated DOM.
javascript
import { mount } from '@vue/test-utils' import { defineComponent, ref } from 'vue' const Counter = defineComponent({ setup() { const count = ref(0) const increment = () => count.value++ return { count, increment } }, template: `<div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> </div>` }) // Wrong: Not waiting for DOM update const wrapper = mount(Counter) wrapper.find('button').trigger('click') console.log(wrapper.text()) // Still "Count: 0" // Right: Wait for next tick await wrapper.find('button').trigger('click') await wrapper.vm.$nextTick() console.log(wrapper.text()) // "Count: 1"
Output
Count: 0
Count: 1
Quick Reference
Here is a quick cheat sheet for common Vue Test Utils methods:
| Method | Description |
|---|---|
| mount(Component) | Mounts a Vue component and returns a wrapper. |
| shallowMount(Component) | Mounts component but stubs child components. |
| wrapper.text() | Returns all text content inside the component. |
| wrapper.html() | Returns the full HTML of the component. |
| wrapper.find(selector) | Finds a DOM element inside the component. |
| wrapper.findComponent(Component) | Finds a child Vue component. |
| wrapper.trigger(event) | Simulates an event like click or input. |
| wrapper.setValue(value) | Sets value on input elements and triggers input event. |
| wrapper.vm | Access the Vue component instance for methods and data. |
| wrapper.emitted() | Returns emitted events from the component. |
Key Takeaways
Use
mount from @vue/test-utils to create a test wrapper for your Vue component.Interact with the wrapper to check text, find elements, and trigger events to test behavior.
Wait for Vue's DOM updates with
await wrapper.vm.$nextTick() after events before asserting changes.Use
shallowMount to stub child components when you want isolated tests.Always import your component and
@vue/test-utils correctly to avoid errors.