Стабирование компонентов (stub)

Стабирование компонентов — ключевой инструмент при тестировании Vue-приложений. Оно позволяет изолировать компонент, заменяя его дочерние компоненты упрощёнными версиями (stubs), что упрощает проверку логики и взаимодействий без необходимости рендерить полный компонентный дерево.

Зачем используется стабирование

Основные цели стабов:

  • Изоляция тестируемого компонента — дочерние компоненты могут содержать сложную логику или сторонние зависимости. Стабирование предотвращает влияние этих зависимостей на тест.
  • Ускорение тестов — stubs рендерятся быстрее, чем полноценные компоненты.
  • Контроль поведения дочерних компонентов — stubs позволяют возвращать предсказуемые данные и события.

Основы использования stubs

В Vue Test Utils stubs создаются при монтировании компонента через опцию global.stubs. Например:

import { mount } from '@vue/test-utils';
import ParentComponent from '@/components/ParentComponent.vue';
import ChildComponent from '@/components/ChildComponent.vue';

const wrapper = mount(ParentComponent, {
  global: {
    stubs: {
      ChildComponent: true
    }
  }
});

В этом примере ChildComponent заменяется простым заглушечным компонентом, который рендерится как пустой элемент <child-component-stub></child-component-stub>.

Автоматическое и ручное стабирование

Vue Test Utils может автоматически стабировать компоненты, если они импортируются как глобальные или локальные, используя булевый флаг true:

global: {
  stubs: ['ChildComponent'] // аналогично { ChildComponent: true }
}

Для более сложных случаев возможна передача собственного шаблона или реализации stubs:

global: {
  stubs: {
    ChildComponent: {
      template: '<div class="stub">Stub Content</div>'
    }
  }
}

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

Взаимодействие с событиями

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

const wrapper = mount(ParentComponent, {
  global: {
    stubs: {
      ChildComponent: {
        template: '<button @click="$emit(\'custom-event\')">Stub Button</button>'
      }
    }
  }
});

await wrapper.find('button').trigger('click');
expect(wrapper.emitted('custom-event')).toBeTruthy();

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

Контроль атрибутов и пропсов

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

global: {
  stubs: {
    ChildComponent: {
      props: ['title'],
      template: '<div>{{ title }}</div>'
    }
  }
}

Это особенно полезно при тестировании интерфейсных связей и реактивного поведения.

Стабирование сторонних библиотек

Сторонние UI-компоненты, например из Vuetify или Element Plus, часто содержат сложные шаблоны и внутренние зависимости. Стабирование позволяет заменять их на минимальные версии:

global: {
  stubs: {
    'v-btn': { template: '<button><slot /></button>' },
    'el-dialog': { template: '<div class="dialog-stub"><slot /></div>' }
  }
}

Таким образом, тест не зависит от реализации сторонней библиотеки и проверяет только логику приложения.

Отличие stubs от mocks

  • Stubs подменяют компонент визуально и функционально для изоляции теста.
  • Mocks подменяют методы или свойства объекта для контроля поведения без изменения структуры.

Использование stubs рекомендуется для тестирования взаимодействий между компонентами, а mocks — для контроля внутренних функций и методов.

Полезные советы

  • Использовать stubs для всех компонентов, которые не являются предметом теста, чтобы ускорить выполнение тестов.
  • Для сложных компонентов иногда полезно использовать частичный stub: рендерить только часть шаблона, оставляя логику минимальной.
  • Следить за тем, чтобы stub не добавлял лишнюю логику, которая может исказить результаты теста.

Стабирование компонентов — фундаментальный инструмент при модульном тестировании Vue. Оно позволяет контролировать окружение теста, изолировать зависимости и сосредоточиться на проверке ключевой логики.