При тестировании Vue-компонентов одним из ключевых аспектов является проверка того, сколько элементов определённого типа или с определённым селектором отображается в компоненте. Это особенно важно при работе с динамическими списками, таблицами, формами и любыми элементами, количество которых может зависеть от состояния компонента или переданных пропсов.
Vue Test Utils предоставляет несколько методов для поиска элементов:
wrapper.find(selector) — возвращает
первый найденный элемент, соответствующий
селектору.wrapper.findAll(selector) — возвращает массив
всех элементов, соответствующих селектору, обёрнутых в объект
WrapperArray.Для проверки количества элементов необходимо использовать именно
findAll, так как find всегда возвращает только
один элемент и не позволяет проверить общее количество.
import { mount } from '@vue/test-utils'
import ItemList from '@/components/ItemList.vue'
const wrapper = mount(ItemList, {
props: {
items: ['apple', 'banana', 'orange']
}
})
const listItems = wrapper.findAll('li')
expect(listItems).toHaveLength(3)
В этом примере тест проверяет, что компонент ItemList
рендерит три элемента списка. toHaveLength является удобным
методом Jest для проверки длины массива.
Для компонентов, которые изменяют своё состояние динамически,
проверка количества элементов требует учёта реактивности Vue. Если
элементы добавляются или удаляются после обновления состояния,
необходимо вызвать await wrapper.vm.$nextTick() перед
проверкой:
import { mount } from '@vue/test-utils'
import TodoList from '@/components/TodoList.vue'
const wrapper = mount(TodoList)
wrapper.vm.addTodo('New Task')
await wrapper.vm.$nextTick()
const todos = wrapper.findAll('li')
expect(todos).toHaveLength(1)
Без nextTick тест может выполнить проверку до того, как
DOM обновится, и количество элементов будет неверным.
Иногда необходимо проверить не точное количество, а наличие
элементов. В этом случае можно использовать комбинацию find
и exists():
const wrapper = mount(MyComponent)
expect(wrapper.find('.error-message').exists()).toBe(true)
expect(wrapper.findAll('.item')).not.toHaveLength(0)
Использование exists() удобно для булевых проверок, а
findAll().length — для точного подсчёта.
findAll может принимать как CSS-селекторы, так и
Vue-компоненты. Это позволяет проверять количество вложенных
компонентов:
import ChildComponent from '@/components/ChildComponent.vue'
const wrapper = mount(ParentComponent, {
props: {
children: [1, 2, 3]
}
})
const childWrappers = wrapper.findAllComponents(ChildComponent)
expect(childWrappers).toHaveLength(3)
findAllComponents удобен при тестировании структур с
компонентами, которые имеют сложные внутренние шаблоны, а не простые
HTML-элементы.
Иногда нужно проверять количество элементов, удовлетворяющих
определённому условию. Для этого можно использовать фильтрацию массива
WrapperArray:
const wrapper = mount(ItemList, {
props: {
items: [
{ name: 'apple', inStock: true },
{ name: 'banana', inStock: false },
{ name: 'orange', inStock: true }
]
}
})
const availableItems = wrapper.findAll('li').filter(item => item.text().includes('apple') || item.text().includes('orange'))
expect(availableItems).toHaveLength(2)
Фильтрация позволяет проверять более сложные сценарии, когда элементы могут быть одинаковыми по тегу, но различаться по содержимому.
findAll и toHaveLength.find().exists().await wrapper.vm.$nextTick().findAllComponents, что
делает тесты более надёжными и не зависит от структуры DOM.Эти техники позволяют создавать детализированные тесты, которые проверяют как статическое содержимое, так и динамическое поведение компонентов, гарантируя корректное отображение элементов в различных состояниях приложения.