Vue Test Utils (VTU) — официальная библиотека для юнит-тестирования
компонентов Vue.js. Она обеспечивает изоляцию компонентов, управление их
состоянием и удобный доступ к DOM через обертку компонента
(wrapper). Основные функции VTU включают:
рендеринг компонентов (mount и shallowMount),
взаимодействие с их пропсами и событиями, а также асинхронное
тестирование с реактивностью Vue.
mount полностью рендерит компонент с
дочерними компонентами.shallowMount рендерит компонент без
вложенных компонентов, заменяя их заглушками. Это ускоряет тесты и
позволяет сосредоточиться на тестируемом компоненте.Пример базового рендеринга:
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent, {
props: { title: 'Тест' }
})
expect(wrapper.text()).toContain('Тест')
Пропсы передаются через объект props при
монтировании:
const wrapper = mount(MyComponent, {
props: { count: 5 }
})
expect(wrapper.props('count')).toBe(5)
Слоты позволяют тестировать вставку пользовательского контента:
const wrapper = mount(MyComponent, {
slots: { default: '<p>Слотовый текст</p>' }
})
expect(wrapper.html()).toContain('Слотовый текст')
Эмит события проверяются через метод emitted():
wrapper.vm.$emit('custom-event', 42)
expect(wrapper.emitted('custom-event')[0]).toEqual([42])
Компоненты Vue используют реактивные данные, поэтому тесты часто
требуют ожидания обновления DOM после изменения состояния. VTU
предоставляет nextTick из Vue:
import { nextTick } from 'vue'
wrapper.setData({ message: 'Новое сообщение' })
await nextTick()
expect(wrapper.text()).toContain('Новое сообщение')
Для промисов и асинхронных вызовов можно использовать
await wrapper.vm.$nextTick() или flushPromises
из вспомогательных библиотек.
Для постепенной миграции старого кода на Vue 3 полезно использовать шаговую стратегию тестирования:
shallowMount для игнорирования сложных
дочерних компонентов.Пример изоляции дочернего компонента:
const wrapper = shallowMount(ParentComponent, {
global: {
stubs: ['ChildComponent'] // заменяет реальный компонент заглушкой
}
})
expect(wrapper.findComponent({ name: 'ChildComponent' }).exists()).toBe(true)
VTU позволяет подключать плагины Vue и глобальные компоненты через
объект global. Это особенно важно при миграции проектов с
Vue 2 на Vue 3, когда используются сторонние библиотеки:
import { createStore } from 'vuex'
const store = createStore({ state: { count: 0 } })
const wrapper = mount(MyComponent, {
global: { plugins: [store] }
})
expect(wrapper.vm.$store.state.count).toBe(0)
nextTick для проверки корректного
обновления DOM.shallowMount — для изоляции сложных компонентов.flush-promises — для тестирования промисов и
асинхронных вызовов.stubs и mocks — для имитации глобальных
компонентов и функций.nextTick и await wrapper.vm.$nextTick() —
для корректной проверки реактивных изменений.Стратегия постепенной миграции с Vue Test Utils позволяет минимизировать риск регрессий, точно контролировать поведение компонентов и последовательно интегрировать новые версии компонентов и библиотек.