Двусторонняя привязка данных в Vue реализуется через директиву
v-model. Она позволяет синхронизировать значение состояния
компонента с пользовательским интерфейсом. При изменении данных в модели
автоматически обновляется отображение, и наоборот — изменение в UI
отражается в состоянии компонента. Тестирование двусторонней привязки
требует проверки корректного взаимодействия модели и представления.
v-modelVue Test Utils предоставляет набор инструментов для изолированного
тестирования компонентов. Основной объект — mount или
shallowMount, позволяющий создавать экземпляры компонента и
работать с их данными и DOM.
Пример базового подхода:
import { mount } from '@vue/test-utils'
import MyInput from '@/components/MyInput.vue'
test('двусторонняя привязка через v-model', async () => {
const wrapper = mount(MyInput, {
props: {
modelValue: ''
}
})
const input = wrapper.find('input')
// Проверка начального значения
expect(input.element.value).toBe('')
// Изменение значения через модель
await wrapper.setProps({ modelValue: 'тест' })
expect(input.element.value).toBe('тест')
// Изменение значения через UI
await input.setValue('новое значение')
expect(wrapper.emitted()['update:modelValue'][0]).toEqual(['новое значение'])
})
Ключевые моменты:
setProps позволяет проверять, как изменения во внешних
свойствах влияют на компонент.setValue эмулирует ввод пользователя и автоматически
инициирует событие input.emitted() фиксирует, что компонент правильно
эмиттирует событие update:modelValue.v-modelДля компонентов с более сложной логикой, где двусторонняя привязка сопровождается валидацией, форматированием или дополнительными событиями, важно тестировать:
Пример теста для компонента с числовым вводом и форматированием:
import { mount } from '@vue/test-utils'
import NumericInput from '@/components/NumericInput.vue'
test('форматирование и двусторонняя привязка', async () => {
const wrapper = mount(NumericInput, {
props: { modelValue: 0 }
})
const input = wrapper.find('input')
// Обновление через UI
await input.setValue('1234')
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([1234])
// Обновление через props
await wrapper.setProps({ modelValue: 5678 })
expect(input.element.value).toBe('5,678') // предполагаемое форматирование
})
Здесь проверяется не только передача значения в модель, но и корректное отображение с форматированием.
v-modelVue 3 позволяет определять кастомные модели с пользовательскими событиями и пропсами. В таких случаях важно явно указывать имя события и проверять его вызовы:
<template>
<input :value="customValue" @input="$emit('change', $event.target.value)">
</template>
<script>
export default {
props: ['customValue']
}
</script>
Тест:
const wrapper = mount(CustomInput, {
props: { customValue: '' }
})
const input = wrapper.find('input')
await input.setValue('abc')
expect(wrapper.emitted().change[0]).toEqual(['abc'])
Проверка кастомного события обеспечивает корректную интеграцию с родительскими компонентами.
setValue:
для v-model важно использовать именно
setValue, чтобы сгенерировалось событие input
или кастомное событие.setProps и setValue должны сопровождаться
await, иначе DOM может быть не обновлён.element.value вместо
emitted: изменение через UI требует проверки
эмитированных событий, иначе тест не подтверждает правильную работу
модели.v-model.v-model.Использование Vue Test Utils позволяет изолировать каждый уровень и гарантировать корректную работу двусторонней привязки независимо от сложности компонента.
Важно учитывать, что двусторонняя привязка напрямую зависит от реактивности Vue. При тестировании реактивных объектов или массивов следует:
reactive или ref при передаче
пропсов в тесте.await nextTick() для
гарантии обновления DOM.Пример с массивом:
import { ref, nextTick } from 'vue'
import { mount } from '@vue/test-utils'
import ListInput from '@/components/ListInput.vue'
test('двусторонняя привязка с массивом', async () => {
const items = ref(['a', 'b'])
const wrapper = mount(ListInput, {
props: { modelValue: items.value }
})
await wrapper.find('input').setValue('c')
await nextTick()
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([['a','b','c']])
})
Этот подход обеспечивает тестирование реактивных структур данных, поддерживая корректную двустороннюю привязку даже при сложных сценариях.