В тестировании компонентов Vue формы требуют особого внимания, так как они включают взаимодействие пользователя с DOM, валидацию данных и часто — асинхронные процессы. Vue Test Utils предоставляет набор инструментов для эффективного моделирования этих взаимодействий и проверки корректности работы компонентов с формами.
Для начала необходимо смонтировать компонент с помощью
mount или shallowMount:
import { mount } from '@vue/test-utils'
import MyForm from '@/components/MyForm.vue'
const wrapper = mount(MyForm)
Важно: mount полностью рендерит
компонент вместе с дочерними компонентами, тогда как
shallowMount создаёт «заглушки» для дочерних компонентов.
Для тестирования форм чаще предпочтителен mount, так как
нужно взаимодействовать с реальными элементами.
Vue Test Utils предоставляет методы для поиска элементов:
wrapper.find(selector) — возвращает первый элемент,
соответствующий селектору.wrapper.findAll(selector) — возвращает коллекцию всех
соответствующих элементов.wrapper.get(selector) — аналог find, но
бросает ошибку, если элемент не найден.Пример поиска полей ввода и кнопки отправки:
const input = wrapper.get('input[name="username"]')
const password = wrapper.get('input[name="password"]')
const submitButton = wrapper.get('button[type="submit"]')
Совет: использовать get, если
отсутствие элемента считается ошибкой теста. Это делает тест более
надёжным.
Для имитации ввода текста используется метод
setValue:
await input.setValue('user123')
await password.setValue('secret')
Метод setValue автоматически обновляет
v-model в компоненте и триггерит события input
или change, если они необходимы.
Ключевой момент: Для асинхронного обновления
состояния компонента после ввода следует использовать
await, чтобы гарантировать завершение всех реактивных
обновлений перед следующими действиями.
Отправку формы можно смоделировать через метод
trigger:
await wrapper.get('form').trigger('submit.prevent')
Здесь используется .prevent, если в компоненте
применяется @submit.prevent для предотвращения стандартного
поведения браузера.
После триггера можно проверить:
jest.fn() или
vi.fn();Пример проверки вызова метода handleSubmit:
const handleSubmit = vi.spyOn(wrapper.vm, 'handleSubmit')
await wrapper.get('form').trigger('submit.prevent')
expect(handleSubmit).toHaveBeenCalled()
Многие формы содержат локальную валидацию. После ввода некорректных данных и отправки формы проверяется появление сообщений об ошибках:
await input.setValue('')
await wrapper.get('form').trigger('submit.prevent')
expect(wrapper.text()).toContain('Поле обязательно для заполнения')
Если используется сторонняя библиотека валидации (например, Vuelidate или Yup), важно подождать асинхронного выполнения проверок:
await wrapper.vm.$nextTick()
или
await flushPromises()
Для чекбоксов используется setChecked:
const checkbox = wrapper.get('input[type="checkbox"]')
await checkbox.setChecked(true)
expect(wrapper.vm.acceptTerms).toBe(true)
Для радиокнопок аналогично:
const option = wrapper.get('input[value="option1"]')
await option.setChecked()
expect(wrapper.vm.selectedOption).toBe('option1')
Особенность: при работе с группами радио и чекбоксов важно правильно выбрать селектор, чтобы тест охватывал нужный элемент.
Если отправка формы инициирует асинхронный процесс (например, запрос
на сервер), используется мок функции fetch или axios:
import axios from 'axios'
vi.mock('axios')
axios.post.mockResolvedValue({ data: { success: true } })
await wrapper.get('form').trigger('submit.prevent')
await flushPromises()
expect(wrapper.vm.successMessage).toBe('Форма успешно отправлена')
flushPromises позволяет дождаться завершения всех
промисов, чтобы тест корректно проверял состояние после асинхронных
операций.
Для форм с динамическими полями (например, добавление нескольких адресов) Vue Test Utils позволяет:
await wrapper.get('button.add-address').trigger('click')
const addresses = wrapper.findAll('input[name="address"]')
expect(addresses.length).toBe(2)
Динамически добавленные элементы можно взаимодействовать точно так же, как статические.
Для комплексной проверки можно использовать снимки состояния (snapshot):
expect(wrapper.html()).toMatchSnapshot()
Это полезно, чтобы убедиться, что после ввода данных и отправки форма рендерится ожидаемым образом, включая сообщения об ошибках или успехе.
await при взаимодействии с
элементами, чтобы реактивность Vue успевала обновляться.get при поиске элементов, чтобы
тесты не проходили незаметно при отсутствии элементов.flushPromises или nextTick.wrapper.vm) и DOM
одновременно для полной уверенности в корректности работы.Работа с формами через Vue Test Utils требует тщательного моделирования пользовательских действий, правильного ожидания асинхронных процессов и внимательного выбора методов поиска элементов. Такой подход обеспечивает надежное покрытие тестами всех сценариев взаимодействия с формами.