Эмуляция пользовательских действий

Эмуляция пользовательских действий является ключевым аспектом при тестировании компонентов Vue, так как позволяет проверять реакцию приложения на события, клики, ввод данных и взаимодействие с формами. Vue Test Utils предоставляет удобные методы для симуляции событий и контроля над поведением компонентов.


Монтирование компонента

Перед эмуляцией действий необходимо создать обёртку компонента с помощью функции mount или shallowMount из Vue Test Utils:

import { mount } from '@vue/test-utils'
import MyButton from '@/components/MyButton.vue'

const wrapper = mount(MyButton)
  • mount полностью рендерит компонент вместе с дочерними компонентами.
  • shallowMount рендерит компонент без глубокого рендера дочерних, что ускоряет тесты и снижает зависимость от внешних компонентов.

После создания wrapper доступен весь интерфейс для взаимодействия с компонентом: поиск элементов, вызов методов, проверка состояния и эмуляция событий.


Методы для эмуляции событий

Основной метод для эмуляции событий — trigger. Он позволяет инициировать DOM-события на выбранных элементах:

const button = wrapper.find('button')
await button.trigger('click')

Особенности trigger:

  • Поддерживаются стандартные события DOM: 'click', 'input', 'submit', 'focus', 'blur'.
  • Можно передавать объект с параметрами события, например:
await button.trigger('keydown', { key: 'Enter' })
  • trigger возвращает промис, что позволяет использовать await для асинхронных обработчиков или обновления состояния компонента после события.

Симуляция ввода текста

Для проверки форм и полей ввода важно корректно эмулировать ввод данных. Vue Test Utils предоставляет комбинацию setValue и trigger('input'):

const input = wrapper.find('input')
await input.setValue('Привет')

Особенности метода setValue:

  • Автоматически обновляет значение элемента value.
  • Эмулирует событие input и изменяет реактивное состояние компонента.
  • Работает с textarea и select.

Для ручной эмуляции ввода можно использовать setValue в связке с trigger:

input.element.value = 'Новое значение'
await input.trigger('input')

Работа с формами и submit

Для тестирования отправки форм используется метод trigger на элементе form:

const form = wrapper.find('form')
await form.trigger('submit.prevent')

Особенности:

  • .prevent эмулирует event.preventDefault().
  • Можно проверять вызовы методов, связанных с отправкой формы, через мок-функции:
const onSub mit = jest.fn()
const wrapper = mount(MyForm, { props: { onSubmit } })
await wrapper.find('form').trigger('submit.prevent')
expect(onSubmit).toHaveBeenCalled()

Клики и события мыши

Для интерактивных компонентов кнопки, переключатели и ссылки проверяются через click и другие мышиные события:

const link = wrapper.find('a')
await link.trigger('click')

Дополнительно можно симулировать более сложные события мыши, передавая объект с координатами, кнопкой мыши и модификаторами:

await button.trigger('mousedown', { button: 0, clientX: 100, clientY: 200 })

Взаимодействие с компонентами через слоты и дочерние компоненты

Vue Test Utils позволяет эмулировать события не только на корневом элементе, но и на дочерних компонентах:

const child = wrapper.findComponent({ name: 'ChildComponent' })
await child.vm.$emit('custom-event', { payload: 123 })

Особенности:

  • $emit используется для создания кастомных событий, которые слушает родитель.
  • Можно проверять реакцию родителя через wrapper.emitted():
expect(wrapper.emitted('child-event')[0]).toEqual([{ payload: 123 }])

Асинхронные события

Многие пользовательские действия вызывают асинхронные процессы: таймеры, запросы к API, обновление состояния. В таких случаях важно использовать await nextTick() или await wrapper.vm.$nextTick() для корректной проверки DOM после события:

import { nextTick } from 'vue'

await button.trigger('click')
await nextTick()
expect(wrapper.text()).toContain('Обновлено')

Проверка состояний после действий

После эмуляции действий проверяется:

  • Содержимое DOM: wrapper.text(), wrapper.html().
  • Состояние компонентов: wrapper.vm.property.
  • Эмиссии событий: wrapper.emitted().
  • Классы и атрибуты: wrapper.classes(), wrapper.attributes().

Пример проверки обновления состояния после клика:

await button.trigger('click')
expect(wrapper.vm.count).toBe(1)
expect(wrapper.text()).toContain('1')

Лучшие практики эмуляции

  1. Использовать setValue для ввода вместо ручного изменения element.value — это обеспечивает корректное обновление реактивности.
  2. Всегда использовать await при эмуляции событий с асинхронной логикой.
  3. Проверять не только вызовы событий, но и конечное состояние компонента.
  4. Использовать селекторы по data-testid для стабильного поиска элементов.
  5. Эмулировать кастомные события на дочерних компонентах через $emit вместо кликов по их DOM, если логика события скрыта внутри компонента.

Эмуляция пользовательских действий в Vue Test Utils обеспечивает полный контроль над поведением компонентов и позволяет тестировать как простые взаимодействия, так и сложные сценарии с формами, асинхронной логикой и кастомными событиями.