Проверка количества элементов

При тестировании 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().
  • Для Vue-компонентов использовать findAllComponents, что делает тесты более надёжными и не зависит от структуры DOM.

Эти техники позволяют создавать детализированные тесты, которые проверяют как статическое содержимое, так и динамическое поведение компонентов, гарантируя корректное отображение элементов в различных состояниях приложения.