Vue Test Utils предоставляет мощные инструменты для
тестирования компонентов Vue, включая встроенные компоненты, такие как
Teleport и Suspense. Их использование в
приложениях становится все более популярным, однако при тестировании
могут возникнуть особенности, которые требуют особого подхода.
Компонент Teleport позволяет рендерить дочерние элементы
в другой части DOM вне текущей иерархии компонента. При тестировании с
Vue Test Utils важно учитывать, что по умолчанию рендеринг происходит в
document.body. Это может вызывать неожиданные результаты
при проверке наличия элементов в дереве компонента.
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent, {
global: {
stubs: {
Teleport: true
}
}
})
Разбор:
global.stubs позволяет заменить реальный
Teleport на стаб, что предотвращает его перенос элементов в
document.body.Если необходимо проверить именно поведение Teleport,
можно рендерить его в реальный DOM:
const wrapper = mount(MyComponent, {
attachTo: document.body
})
attachTo позволяет проверить наличие
элементов в теле документа.Компонент Suspense предназначен для асинхронной загрузки
дочерних компонентов. В тестах он может создавать сложности, так как
рендеринг задерживается до завершения промисов, переданных через
setup или defineAsyncComponent.
import { mount } from '@vue/test-utils'
import AsyncComponent from '@/components/AsyncComponent.vue'
const wrapper = mount({
template: `
<Suspense>
<AsyncComponent />
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
`,
global: {
stubs: {
Suspense: true
}
}
})
Разбор:
Suspense позволяет игнорировать асинхронность и
сразу рендерить дочерние элементы.#fallback) можно тестировать отдельно,
если важно проверить состояние ожидания.Для проверки асинхронного рендеринга без стаба:
import { nextTick } from 'vue'
const wrapper = mount({
template: `
<Suspense>
<AsyncComponent />
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
`
})
expect(wrapper.html()).toContain('Loading...') // отображается фолбэк
await nextTick() // ожидаем рендер асинхронного компонента
expect(wrapper.html()).toContain('Async content') // проверяем итоговый рендер
Особенности:
await nextTick() важно для обработки
промисов, которые Suspense ждет перед рендерингом.Использование стаба Стабирование встроенных
компонентов (Teleport, Suspense) делает тесты
быстрее и предотвращает нежелательное взаимодействие с реальным DOM или
асинхронными процессами.
Тестирование в реальном DOM Если требуется
проверить поведение компонентов в браузере, необходимо использовать
attachTo для Teleport и ожидание nextTick или
flushPromises для Suspense.
Проверка фолбэков Suspense позволяет определить отдельные шаблоны для состояния загрузки. Тестирование этих шаблонов обеспечивает полное покрытие сценариев рендеринга.
Комбинирование стаба и реального рендера Для комплексных компонентов можно использовать частичное стабирование: стабировать Teleport, но оставить Suspense реальным, либо наоборот, в зависимости от цели теста.
Использование стаба встроенных компонентов в Vue Test Utils обеспечивает изоляцию тестов, уменьшает количество побочных эффектов и позволяет создавать предсказуемые, повторяемые сценарии. Это особенно важно для крупных приложений с множеством асинхронных и портируемых элементов интерфейса.