Изменение data (setValue для input)

В Vue Test Utils взаимодействие с компонентами строится на манипуляции их данными, свойствами (props) и событиями. Одним из ключевых аспектов тестирования является изменение значений элементов формы и реакция компонента на эти изменения.

Методы изменения данных

Для изменения data компонента напрямую используется объект vm (Vue instance), доступный через wrapper.vm. Например:

const wrapper = mount(MyComponent, {
  data() {
    return { text: '' }
  }
})

// Изменение значения напрямую
wrapper.vm.text = 'новое значение'

// Проверка изменения
expect(wrapper.vm.text).toBe('новое значение')

Использование wrapper.vm позволяет манипулировать внутренним состоянием компонента без взаимодействия с DOM. Это полезно для тестов логики, не зависящей от пользовательского интерфейса.

Работа с input через setValue

Для имитации пользовательского ввода используется метод setValue, который применяется к элементу формы, найденному через wrapper.find. Этот метод не только изменяет значение поля, но и автоматически триггерит событие input, что делает поведение теста максимально приближённым к реальному.

Пример использования:

const wrapper = mount(MyComponent)
const input = wrapper.find('input[name="username"]')

// Установка нового значения
await input.setValue('JohnDoe')

// Проверка привязки к data
expect(wrapper.vm.username).toBe('JohnDoe')

Ключевые моменты:

  • setValue работает только с интерактивными элементами, такими как <input>, <textarea> и <select>.
  • Метод автоматически вызывает все соответствующие события, включая input и change.
  • Для асинхронных реакций компонента необходимо использовать await перед setValue, чтобы дождаться обновления DOM и реактивной системы Vue.

Отличие setValue от прямого изменения data

Прямое изменение wrapper.vm обновляет состояние компонента, но не изменяет DOM автоматически. Для проверки визуального отображения данных это важно учитывать:

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

// Прямое изменение
wrapper.vm.text = 'Hello'

// DOM не обновлён
expect(wrapper.find('input').element.value).toBe('')

// Правильное изменение через setValue
await wrapper.find('input').setValue('Hello')
expect(wrapper.find('input').element.value).toBe('Hello')

Таким образом, setValue обеспечивает синхронизацию данных и DOM, тогда как vm подходит для тестирования чистой логики компонента.

Тестирование реактивности после изменения

После изменения значения data или использования setValue иногда требуется убедиться, что компонент правильно отреагировал на изменения. Это особенно важно для computed свойств и методов, зависящих от состояния.

const wrapper = mount(MyComponent, {
  data() {
    return { firstName: '', lastName: '' }
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`.trim()
    }
  }
})

await wrapper.find('input[name="firstName"]').setValue('John')
await wrapper.find('input[name="lastName"]').setValue('Doe')

// Проверка реактивности
expect(wrapper.vm.fullName).toBe('John Doe')

Использование setValue гарантирует корректное срабатывание всех реактивных зависимостей, включая вычисляемые свойства, watchers и условный рендеринг.

Практические рекомендации

  • Для тестирования логики компонента изменения через wrapper.vm быстрее и удобнее.
  • Для тестирования взаимодействия с пользователем необходимо использовать setValue.
  • Всегда учитывать асинхронность реактивной системы Vue и использовать await перед setValue или после изменения vm, если проверка связана с DOM.
  • В сложных формах с валидацией или кастомными компонентами setValue позволяет эмулировать именно реальный пользовательский ввод, что делает тесты надёжными.

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