При переходе с Vue 2 на Vue 3 важным аспектом является адаптация тестов компонентов, так как изменилась архитектура фреймворка, API и поведение реактивности. Vue Test Utils (VTU) для Vue 3 предоставляет новые методы и возможности, но также требует пересмотра подходов к тестированию, особенно при работе с слотом, событиями и асинхронной логикой.
1. Новый API рендеринга В Vue 3 VTU используется
функция mount из пакета @vue/test-utils,
аналогично Vue 2, но с расширенной поддержкой Composition API и
Teleport. Компоненты можно монтировать так же, как и раньше:
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent, {
props: { msg: 'Привет' },
global: {
plugins: [],
components: {},
directives: {}
}
})
Ключевой момент: в Vue 3 добавлен объект global, который
позволяет подключать плагины, компоненты и директивы в тестовом
окружении, аналогично localVue в Vue 2, но с более
прозрачным API.
2. Работа с событиями и v-model Vue 3 изменил
внутреннюю реализацию v-model. Теперь компонент может иметь
несколько v-model, что влияет на тестирование:
const wrapper = mount(MyComponent, {
props: {
modelValue: 'тест'
}
})
await wrapper.setValue('новое значение')
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['новое значение'])
Важно проверять события update:modelValue вместо прямой
мутации пропсов, что отличается от подхода Vue 2.
3. Асинхронные обновления DOM Vue 3 использует новую
реактивную систему, которая делает обновления DOM асинхронными. Это
требует использования nextTick или асинхронных ожиданий при
проверке состояния DOM после изменений:
import { nextTick } from 'vue'
await wrapper.setProps({ msg: 'обновлено' })
await nextTick()
expect(wrapper.text()).toContain('обновлено')
Игнорирование асинхронности может привести к ложным отрицательным результатам в тестах.
1. Слоты Слоты в Vue 3 имеют более строгую проверку
типов и могут быть функциональными. Передача слота выполняется через
объект slots:
const wrapper = mount(MyComponent, {
slots: {
default: '<span>Контент слота</span>'
}
})
expect(wrapper.html()).toContain('Контент слота')
2. Teleport Компоненты, использующие
<teleport>, требуют специального подхода. Vue Test
Utils позволяет проверять содержимое, смонтированное в другом месте
DOM:
const wrapper = mount(MyComponent, { attachTo: document.body })
expect(document.body.innerHTML).toContain('Телепортированный контент')
В Vue 2 использовался localVue для подключения плагинов,
Vuex и роутера. В Vue 3 аналог — объект global:
const wrapper = mount(MyComponent, {
global: {
plugins: [store, router],
mocks: {
$t: (msg) => msg
}
}
})
Это упрощает изоляцию компонента и позволяет тестировать без необходимости создавать полноценный экземпляр приложения.
Vue 3 активно использует Composition API. Тестирование реактивных переменных и функций требует прямого доступа к возвращаемым значениям setup:
import { ref } from 'vue'
const wrapper = mount({
template: '<button @click="increment">{{ count }}</button>',
setup() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
})
await wrapper.trigger('click')
expect(wrapper.text()).toBe('1')
Важно помнить, что ref и reactive теперь
полностью интегрированы с VTU, но их значения проверяются через
.text(), .props() или прямой доступ через
wrapper.vm.
nextTick или flushPromises.global
вместо localVue.wrapper.vm и реактивные переменные.v-model для компонентов с несколькими
моделями.import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import MyForm from '@/components/MyForm.vue'
import store from '@/store'
const wrapper = mount(MyForm, {
global: { plugins: [store] },
props: { initialValue: '123' },
slots: { default: '<div>Slot content</div>' }
})
await wrapper.find('input').setValue('456')
await nextTick()
expect(wrapper.emitted('update:modelValue')[0]).toEqual(['456'])
expect(wrapper.html()).toContain('Slot content')
Этот пример показывает интеграцию нескольких аспектов Vue 3: слоты,
глобальные плагины, асинхронное обновление DOM и события
v-model.
Миграция тестов с Vue 2 на Vue 3 требует внимательного анализа компонентов и их реактивной логики, но новая архитектура VTU делает тестирование более модульным и гибким.