Testing Vue components gives you confidence that your UI works as expected. Vitest integrates natively with Vite projects for extremely fast test execution.
npm install -D vitest @vue/test-utils jsdom @vitejs/plugin-vue
// vite.config.js
export default defineConfig({
plugins: [vue()],
test: {
environment: 'jsdom',
globals: true,
},
})
// Counter.test.js
import { mount } from '@vue/test-utils'
import Counter from '@/components/Counter.vue'
describe('Counter', () => {
it('renders initial count', () => {
const wrapper = mount(Counter, { props: { initial: 5 } })
expect(wrapper.text()).toContain('5')
})
it('increments on button click', async () => {
const wrapper = mount(Counter)
await wrapper.find('button').trigger('click')
expect(wrapper.text()).toContain('1')
})
it('emits update event', async () => {
const wrapper = mount(Counter)
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('update')).toBeTruthy()
expect(wrapper.emitted('update')[0]).toEqual([1])
})
})
import { mount, flushPromises } from '@vue/test-utils'
import { vi } from 'vitest'
import UserList from '@/components/UserList.vue'
vi.mock('@/api/axios', () => ({
default: {
get: vi.fn().mockResolvedValue({
data: [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }],
}),
},
}))
it('renders users after fetch', async () => {
const wrapper = mount(UserList)
await flushPromises()
expect(wrapper.findAll('li')).toHaveLength(2)
expect(wrapper.text()).toContain('Alice')
})
npx vitest # watch mode
npx vitest run # single run (CI)
npx vitest --ui # browser UI
All Comments