0
0
VueHow-ToBeginner · 4 min read

How to Test Vue Component: Simple Guide with Examples

To test a Vue component, use @vue/test-utils to mount the component and Jest to run assertions on its behavior or output. Write tests that check rendered HTML, component methods, or emitted events to ensure your component works as expected.
📐

Syntax

Use mount() from @vue/test-utils to create a wrapper around your component. Then use Jest's expect() to check the output or behavior.

  • mount(Component): renders the component for testing.
  • wrapper.text(): gets the text content.
  • wrapper.find(selector): finds elements inside the component.
  • expect(value).toBe(expected): asserts expected results.
javascript
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'

test('renders message', () => {
  const wrapper = mount(MyComponent)
  expect(wrapper.text()).toContain('Hello')
})
💻

Example

This example shows a simple Vue component with a button that increments a counter. The test mounts the component, clicks the button, and checks if the counter updates.

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><button @click=\"increment\">Increment</button><p>Count: {{ count }}</p></div>`
})

test('increments count on button click', async () => {
  const wrapper = mount(Counter)
  expect(wrapper.text()).toContain('Count: 0')
  await wrapper.find('button').trigger('click')
  expect(wrapper.text()).toContain('Count: 1')
})
Output
PASS increments count on button click
⚠️

Common Pitfalls

Not waiting for DOM updates: Vue updates the DOM asynchronously, so use await with events like trigger() to wait for updates.

Testing implementation details: Avoid testing private methods or internal state; test what the user sees or interacts with.

Not cleaning up: Each test should mount fresh components to avoid shared state.

javascript
/* Wrong: missing await causes test to fail */
await wrapper.find('button').trigger('click') // Correct
wrapper.find('button').trigger('click') // Wrong

/* Wrong: testing internal data directly */
expect(wrapper.vm.count).toBe(1) // Less preferred

/* Right: test visible output */
expect(wrapper.text()).toContain('Count: 1')
📊

Quick Reference

ActionMethodDescription
Mount componentmount(Component)Render component for testing
Find elementwrapper.find(selector)Select element inside component
Get textwrapper.text()Get all text content
Trigger eventwrapper.find('button').trigger('click')Simulate user event
Assert valueexpect(value).toBe(expected)Check expected result

Key Takeaways

Use @vue/test-utils mount() to render components for testing.
Always await DOM updates after events with async/await.
Test visible output or emitted events, not internal state.
Write isolated tests to avoid shared component state.
Use Jest expect() assertions to verify component behavior.