Тестирование именованных слотов (named slots)

Именованные слоты в Vue позволяют компонентам быть более гибкими, предоставляя возможность вставлять содержимое в определённые части компонента. Для комплексного тестирования таких компонентов важно понимать, как Vue Test Utils взаимодействует со слотами и как проверять их поведение.

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

В Vue компонент может определять несколько слотов с разными именами:

<template>
  <div class="card">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

В этом примере:

  • header и footer — именованные слоты.
  • Основной слот (без имени) — для контента по умолчанию.

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

Передача именованных слотов в тестах

Vue Test Utils предоставляет возможность передавать слоты через опцию slots при монтировании компонента:

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

const wrapper = mount(Card, {
  slots: {
    header: '<h1>Заголовок</h1>',
    default: '<p>Основной контент</p>',
    footer: '<small>Подвал</small>'
  }
})

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

  • Имя ключа в объекте slots должно точно соответствовать имени слота в компоненте.
  • Содержимое слота передаётся как строка с HTML или как компонент Vue.

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

После монтирования компонента можно проверять, что контент слотов отображается корректно:

expect(wrapper.find('header h1').text()).toBe('Заголовок')
expect(wrapper.find('main p').text()).toBe('Основной контент')
expect(wrapper.find('footer small').text()).toBe('Подвал')

При этом find ищет элементы в DOM компонента, что позволяет убедиться, что переданный слот корректно встроился.

Использование Vue компонентов в слотах

Слоты могут содержать не только строковый HTML, но и другие компоненты:

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

const wrapper = mount(Card, {
  slots: {
    header: CustomHeader
  }
})

Vue Test Utils автоматически рендерит переданный компонент в слот. Проверка его наличия осуществляется через методы findComponent или exists:

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

Динамические слоты и слоты с пропсами

Некоторые компоненты передают данные в слот через v-slot. Для тестирования таких сценариев важно передавать функцию:

<slot name="item" :text="itemText"></slot>

В тесте это можно эмулировать так:

const wrapper = mount(ListComponent, {
  slots: {
    item: '<template #item="{ text }"><li>{{ text }}</li></template>'
  }
})

Проверка рендеринга может включать поиск всех элементов li и проверку их текста:

const items = wrapper.findAll('li')
expect(items[0].text()).toBe('Первый элемент')

Тестирование условных слотов

Если слот отображается только при определённых условиях, важно учитывать реактивность:

<slot v-if="showFooter" name="footer"></slot>

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

await wrapper.setData({ showFooter: true })
expect(wrapper.find('footer').exists()).toBe(true)

await wrapper.setData({ showFooter: false })
expect(wrapper.find('footer').exists()).toBe(false)

Советы по написанию тестов для именованных слотов

  • Использовать точные имена слотов при передаче через slots.
  • Для компонентов в слотах применять findComponent для проверки их рендеринга.
  • При слоте с пропсами проверять, что данные корректно передаются и используются.
  • В динамических сценариях проверять реактивное поведение и условные рендеры.
  • Избегать тестирования внутренней структуры слота, сосредотачиваясь на итоговом рендере.

Заключение по практическим аспектам

Именованные слоты увеличивают гибкость компонентов, а Vue Test Utils предоставляет полный инструментарий для их тестирования: передача контента, проверка рендеринга, использование компонентов и слотов с пропсами, а также проверка динамических условий. Правильная структура тестов позволяет обеспечить стабильность компонентов даже при сложных комбинациях слотов.