Проверка содержимого слота

В Vue.js слоты позволяют компонентам быть гибкими и расширяемыми за счёт передачи содержимого из родительского компонента. Тестирование слотов является важной частью обеспечения корректного поведения компонентов, особенно если логика или отображение зависит от динамического содержимого.

Основы работы со слотами

В Vue Test Utils слоты передаются при создании обёртки компонента с помощью метода mount или shallowMount через опцию slots. Эта опция принимает объект, где ключи соответствуют именам слотов, а значения — содержимому, которое будет вставлено.

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

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

const wrapper = mount(MyComponent, {
  slots: {
    default: '<p>Текст слота</p>',
    header: '<h1>Заголовок</h1>'
  }
})

В этом примере компонент MyComponent получает два слота: default и header. Содержимое будет отрендерено внутри соответствующих <slot> тегов компонента.

Проверка содержимого слота

Для проверки содержимого используется метод html() или селекторы внутри обёртки компонента. Часто проверяют:

  • наличие текста
  • правильное размещение элементов
  • реакцию на изменения слота

Пример проверки текста слота:

expect(wrapper.html()).toContain('Текст слота')

Можно также использовать метод find для более точного поиска элементов внутри слота:

expect(wrapper.find('p').text()).toBe('Текст слота')
expect(wrapper.find('h1').exists()).toBe(true)

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

Динамическое содержимое слота

Слоты часто зависят от данных родителя. Чтобы проверить динамическое поведение, создаются обёртки с изменяемыми пропсами или реактивными данными. Например:

import { reactive } from 'vue'

const state = reactive({ message: 'Привет' })

const wrapper = mount(MyComponent, {
  slots: {
    default: `<p>${state.message}</p>`
  }
})

expect(wrapper.find('p').text()).toBe('Привет')

state.message = 'Пока'
await wrapper.vm.$nextTick()

expect(wrapper.find('p').text()).toBe('Пока')

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

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

Содержимое слота может быть другим компонентом. В этом случае проверка ведётся через findComponent или findAllComponents:

import ChildComponent from '@/components/ChildComponent.vue'

const wrapper = mount(MyComponent, {
  slots: {
    default: ChildComponent
  }
})

expect(wrapper.findComponent(ChildComponent).exists()).toBe(true)

Также можно передавать компонент с пропсами, используя функцию рендеринга:

const wrapper = mount(MyComponent, {
  slots: {
    default: (props) => h(ChildComponent, { title: props.title })
  }
})

Это позволяет тестировать слоты, которые используют v-slot с передачей параметров из компонента.

Тестирование fallback-контента

Если слот не передан, Vue рендерит fallback-контент. Проверка этого поведения необходима для обеспечения корректного отображения:

const wrapper = mount(MyComponent)

expect(wrapper.find('.default-slot').text()).toBe('Контент по умолчанию')

Здесь .default-slot — элемент, в котором находится дефолтный контент слота.

Комбинирование слотов и событий

Слоты могут содержать интерактивные элементы, которые вызывают события компонента. Для проверки взаимодействия важно соединять проверку слота и событий:

const wrapper = mount(MyComponent, {
  slots: {
    default: '<button class="btn">Клик</button>'
  }
})

await wrapper.find('button').trigger('click')
expect(wrapper.emitted()).toHaveProperty('button-clicked')

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

Лучшие практики тестирования слотов

  1. Изолированная проверка — тестировать слот отдельно от сложной логики компонента, когда это возможно.
  2. Использование селекторов — для точной проверки элементов слота лучше использовать классы или атрибуты.
  3. Проверка реактивности — если слот зависит от пропсов или реактивных данных, проверять обновление после изменений.
  4. Комбинированные сценарии — тестировать слоты с событиями и дочерними компонентами для полного покрытия.
  5. Fallback-контент — всегда проверять поведение при отсутствии переданного слота.

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