Стабы и моки при монтировании

При тестировании компонентов Vue одним из ключевых аспектов является изоляция тестируемого компонента от внешних зависимостей. Для этого используются стабы (stubs) и моки (mocks), которые позволяют заменить реальную реализацию зависимостей упрощёнными или имитированными версиями. Это повышает стабильность тестов и ускоряет их выполнение.


Стабы компонентов

Стаб — это упрощённая версия дочернего компонента, используемая вместо полной реализации при монтировании родительского компонента. Основная цель стаба — изолировать тестируемый компонент от сложной или внешней логики.

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: {
        template: '<div class="stub">Стаб компонента</div>'
      }
    }
  }
});

console.log(wrapper.html()); 
// В HTML будет <div class="stub">Стаб компонента</div>

Особенности использования стубов:

  • Минимализм: Стабы должны содержать только необходимую структуру или события.
  • События: Можно симулировать события дочернего компонента, чтобы тестировать реакцию родителя.
  • Автоматические стабы: Vue Test Utils позволяет автоматически создавать стабы для всех дочерних компонентов с помощью строки 'stubs: ['ChildComponent']'.
mount(ParentComponent, {
  global: {
    stubs: ['ChildComponent']
  }
});
  • Автоматические стабы удобны для уменьшения объема тестируемого кода, но при сложной логике дочернего компонента лучше создавать кастомные стабы, чтобы контролировать поведение и события.

Моки глобальных свойств

Моки применяются для подмены глобальных объектов или методов, таких как $router, $store или $t (для i18n). Это позволяет избежать необходимости реальной конфигурации плагинов и сервисов.

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

const wrapper = mount(MyComponent, {
  global: {
    mocks: {
      $t: (msg) => msg, // Подмена метода перевода
      $router: {
        push: jest.fn() // Подмена метода роутера
      }
    }
  }
});

wrapper.vm.$router.push('/home');
expect(wrapper.vm.$router.push).toHaveBeenCalledWith('/home');

Ключевые моменты при использовании моков:

  • Моки позволяют тестировать реакции компонента на вызовы методов, не вызывая реальную логику.
  • Моки можно комбинировать с jest.fn() для отслеживания вызовов и параметров.
  • Используются для глобальных сервисов, контекста, а также для подмены API-запросов внутри компонентов.

Монтирование с использованием стубов и моков

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

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: {
        template: '<button @click="$emit(\'custom-event\')">Click</button>'
      }
    },
    mocks: {
      $store: {
        state: { count: 0 },
        commit: jest.fn()
      }
    }
  }
});

wrapper.find('button').trigger('click');
expect(wrapper.vm.$store.commit).not.toHaveBeenCalled(); // Родитель может реагировать на событие

Важные рекомендации:

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

Частые ошибки при использовании стубов и моков

  1. Замена слишком большой логики: Стабы должны имитировать только интерфейс, а не всю бизнес-логику. Подмена всего компонента усложняет тесты и скрывает ошибки.
  2. Забытые события: При кастомных стабах важно вручную пробрасывать события, иначе родительский компонент не получит сигнал.
  3. Моки вместо реального функционала: Чрезмерное использование моков для методов компонента снижает достоверность тестов. Моки должны использоваться только для внешних зависимостей.

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

  • Тестирование форм и пользовательского ввода: стабы кнопок или полей позволяют проверять обработку событий.
  • Подмена глобальных сервисов: $store, $router, $axios через моки упрощает интеграционные проверки.
  • Изоляция компонентов при тестах сложных деревьев компонентов, чтобы уменьшить количество зависимостей и ускорить тесты.

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