Тестирование нативных событий DOM

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


Использование метода trigger

Метод trigger применяется к обёртке компонента (wrapper) и инициирует указанное событие. Он имитирует реальное поведение браузера и вызывает соответствующие слушатели событий в компоненте.

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

const wrapper = mount(ButtonComponent)

// Триггер события click
await wrapper.find('button').trigger('click')

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

  • Поддерживает стандартные DOM-события: click, input, focus, blur, keydown и др.
  • Позволяет передавать объект с дополнительными параметрами события:
await wrapper.find('input').trigger('keydown', { key: 'Enter' })
  • Асинхронная обработка событий: при изменении состояния компонента внутри обработчика события необходимо использовать await nextTick() или асинхронный trigger.
import { nextTick } from 'vue'

await wrapper.find('button').trigger('click')
await nextTick()
expect(wrapper.text()).toContain('Нажато')

Передача данных событий

Нативные события часто содержат специфичные свойства, такие как target.value для input или clientX и clientY для мыши. Для их передачи используется второй аргумент метода trigger:

await wrapper.find('input').trigger('input', { target: { value: 'Vue' } })
expect(wrapper.vm.text).toBe('Vue')

Для событий мыши:

await wrapper.find('div').trigger('mousemove', { clientX: 100, clientY: 200 })

Это позволяет эмулировать реальные сценарии взаимодействия с компонентом.


Проверка вызова обработчиков событий

Vue Test Utils интегрируется с Jest и другими тестовыми фреймворками для мокирования функций:

const clickHandler = jest.fn()
const wrapper = mount(ButtonComponent, {
  props: { onClick: clickHandler }
})

await wrapper.find('button').trigger('click')
expect(clickHandler).toHaveBeenCalledTimes(1)

Для кастомных событий, объявленных через $emit, проверка выполняется аналогично:

await wrapper.find('button').trigger('click')
expect(wrapper.emitted('customEvent')).toBeTruthy()
expect(wrapper.emitted('customEvent')[0]).toEqual(['payload'])

Работа с формами и вводом текста

Для input и textarea Vue Test Utils предоставляет два подхода: нативные события и вспомогательные методы setValue:

const wrapper = mount({
  template: `<input v-model="text" />`,
  data() { return { text: '' } }
})

// Использование trigger
await wrapper.find('input').trigger('input', { target: { value: 'Тест' } })
expect(wrapper.vm.text).toBe('Тест')

// Использование setValue (удобнее для v-model)
await wrapper.find('input').setValue('Тест 2')
expect(wrapper.vm.text).toBe('Тест 2')

setValue автоматически вызывает событие input и обновляет v-model, что упрощает тестирование форм.


Симуляция фокуса и потери фокуса

Фокусировка и размытие элементов часто важны для проверки поведения валидации или отображения подсказок:

await wrapper.find('input').trigger('focus')
expect(wrapper.classes()).toContain('focused')

await wrapper.find('input').trigger('blur')
expect(wrapper.classes()).not.toContain('focused')

Триггер событий клавиатуры

События клавиатуры могут включать сочетания клавиш, что важно для проверки логики навигации или форм:

await wrapper.find('input').trigger('keydown', { key: 'Enter', code: 'Enter' })
await wrapper.find('input').trigger('keyup', { key: 'Enter' })

Можно проверять реакции компонента на специфические клавиши, включая модификаторы (shiftKey, ctrlKey, altKey, metaKey):

await wrapper.find('input').trigger('keydown', { key: 'A', ctrlKey: true })

Триггер нестандартных событий

Если компонент реагирует на события, которых нет в DOM по умолчанию, их можно вызвать вручную через trigger с именем события:

await wrapper.find('div').trigger('custom-event', { detail: { id: 1 } })
expect(wrapper.emitted('custom-event')[0]).toEqual([{ id: 1 }])

Рекомендации по структуре тестов

  1. Изолированность: Каждый тест должен проверять одно событие.
  2. Асинхронность: Любые изменения состояния после события требуют await nextTick().
  3. Полное покрытие: Тестировать все возможные сценарии события — успешное выполнение, ошибки, пустые значения.
  4. Использование find и findAll: Для одиночных элементов find, для списка элементов findAll.

Тестирование нативных событий DOM с помощью Vue Test Utils предоставляет мощные возможности для проверки интерактивного поведения компонентов. Метод trigger в сочетании с передачей данных событий и асинхронной обработкой обеспечивает точное воспроизведение взаимодействия пользователя, а проверка через emitted или мок-функции позволяет уверенно утверждать корректность работы обработчиков.