Vue Test Utils (VTU) — официальная библиотека для тестирования
компонентов Vue.js. Она предоставляет набор утилит для рендеринга
компонентов, симуляции событий и проверки реактивного поведения.
Основной элемент VTU — mount и
shallowMount, которые создают экземпляр
компонента для теста.
mount полностью рендерит компонент со
всеми его дочерними компонентами.shallowMount рендерит только сам
компонент, заменяя дочерние компоненты заглушками. Это ускоряет
тестирование и снижает сложность.Пример базового использования:
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent)
expect(wrapper.text()).toContain('Привет, Vue!')
VTU предоставляет методы для работы с DOM-узлами компонента. Основные методы:
find(selector) — возвращает первый
элемент, соответствующий селектору.findAll(selector) — возвращает массив
всех элементов, подходящих под селектор.text() — извлекает текстовое
содержимое элемента.html() — возвращает HTML-разметку
компонента.attributes(name) — получает значение
указанного атрибута.Пример поиска и проверки:
const button = wrapper.find('button')
expect(button.text()).toBe('Нажми меня')
expect(button.attributes('disabled')).toBeUndefined()
VTU позволяет эмулировать пользовательские события, что критично для тестирования интерактивных компонентов.
trigger(event, options) — запускает
событие на элементе.Пример:
const button = wrapper.find('button')
button.trigger('click')
expect(wrapper.emitted('clicked')).toHaveLength(1)
emitted() возвращает объект с массивами вызовов событий,
что позволяет проверять аргументы и количество срабатываний.
Компоненты Vue часто используют props для передачи данных и data/computed для управления состоянием. VTU поддерживает настройку этих значений при монтировании:
const wrapper = mount(MyComponent, {
props: { title: 'Тестовый заголовок' },
data() {
return { count: 5 }
}
})
expect(wrapper.props('title')).toBe('Тестовый заголовок')
expect(wrapper.vm.count).toBe(5)
wrapper.vm предоставляет доступ к экземпляру
компонента, включая методы и вычисляемые свойства.props после монтирования можно тестировать
через setProps().wrapper.setProps({ title: 'Новый заголовок' })
expect(wrapper.text()).toContain('Новый заголовок')
Слоты позволяют вставлять пользовательский контент в компонент. VTU
поддерживает передачу слотов через объект slots:
const wrapper = mount(MyComponent, {
slots: { default: '<p>Слот-контент</p>' }
})
expect(wrapper.html()).toContain('<p>Слот-контент</p>')
Также можно тестировать именованные слоты:
const wrapper = mount(MyComponent, {
slots: { header: '<h1>Заголовок</h1>' }
})
expect(wrapper.find('h1').text()).toBe('Заголовок')
Для компонентов, которые зависят от глобальных ресурсов, VTU предоставляет возможность мока:
global.mocks — подменяет глобальные
объекты, например $router, $store.global.stubs — подменяет дочерние
компоненты заглушками.Пример мока Vuex:
const storeMock = { dispatch: jest.fn() }
const wrapper = mount(MyComponent, {
global: { mocks: { $store: storeMock } }
})
wrapper.vm.someAction()
expect(storeMock.dispatch).toHaveBeenCalledWith('someAction')
VTU поддерживает асинхронные операции с использованием
nextTick или flushPromises:
import { nextTick } from 'vue'
wrapper.setData({ count: 10 })
await nextTick()
expect(wrapper.text()).toContain('10')
flushPromises полезен для тестирования промисов и
API-запросов:
import flushPromises from 'flush-promises'
await wrapper.vm.fetchData()
await flushPromises()
expect(wrapper.text()).toContain('Данные загружены')
VTU позволяет проверять динамические классы и стили:
expect(wrapper.classes()).toContain('active')
expect(wrapper.find('div').element.style.color).toBe('red')
Методы:
classes() — массив всех классов
элемента.hasClass(className) — проверка наличия
конкретного класса.element.style — доступ к
инлайн-стилям.Для ускорения тестирования можно создавать обёртки-компоненты (wrapper components), которые заранее подставляют пропсы, слоты и моки. Это уменьшает повторение кода и позволяет тестировать сложные UI-модули с минимальными усилиями.
Пример обёртки:
const TestButtonWrapper = {
template: '<MyButton @clicked="onClick" :label="label" />',
components: { MyButton },
data() { return { label: 'Тест' } },
methods: { onClick: jest.fn() }
}
const wrapper = mount(TestButtonWrapper)
wrapper.find('button').trigger('click')
expect(wrapper.vm.onClick).toHaveBeenCalled()
Такие компоненты особенно полезны при интеграционном тестировании и работе с библиотеками UI, где нужно проверять комбинацию нескольких готовых компонентов.
VTU предоставляет удобный метод
wrapper.debug(), который выводит структуру
компонента с вложенными элементами. Это облегчает поиск проблем при
сложных шаблонах:
console.log(wrapper.debug())
Метод возвращает читаемую строку, показывающую компоненты, их props, слоты и текстовое содержимое.
shallowMount для
юнит-тестов отдельных компонентов.mount для интеграционных
тестов с дочерними компонентами.nextTick или
flushPromises для корректного ожидания обновлений.Эти подходы обеспечивают надежное покрытие и читаемость тестов при работе с Vue Test Utils.