Vue Test Utils библиотека

Vue Test Utils — официальная библиотека для тестирования компонентов Vue.js. Она обеспечивает удобный и мощный API для юнит-тестирования, позволяя взаимодействовать с компонентами, проверять их поведение и состояние без необходимости рендерить полноценное приложение.

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


Монтирование компонентов

Для тестирования компонент необходимо их монтировать. Vue Test Utils предоставляет два основных метода:

  • mount — полный рендер компонента, включая все дочерние компоненты.
  • shallowMount — частичный рендер, при котором дочерние компоненты заменяются заглушками, что ускоряет тестирование и упрощает изоляцию.

Пример:

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

const wrapper = mount(MyComponent);
const shallowWrapper = shallowMount(MyComponent);

wrapper — объект, через который осуществляется взаимодействие с компонентом: чтение данных, вызов методов, проверка состояния DOM.


Работа с пропсами и данными

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

const wrapper = mount(MyComponent, {
  props: {
    title: 'Тестовый заголовок'
  },
  data() {
    return {
      count: 5
    };
  }
});

expect(wrapper.props('title')).toBe('Тестовый заголовок');
expect(wrapper.vm.count).toBe(5);
  • props задают входные параметры компонента.
  • data() позволяет инициализировать реактивное состояние.
  • wrapper.vm предоставляет доступ к экземпляру Vue компонента, включая методы, вычисляемые свойства и реактивные данные.

Взаимодействие с DOM

Vue Test Utils позволяет имитировать пользовательские действия и проверять изменения в DOM:

  • trigger — вызывает событие на элементе.
  • setValue — изменяет значение инпута.
  • setChecked — устанавливает состояние чекбокса или радио-кнопки.

Пример:

const wrapper = mount(MyComponent);
const button = wrapper.find('button');

button.trigger('click');
expect(wrapper.vm.count).toBe(6);

const input = wrapper.find('input');
input.setValue('Новое значение');
expect(wrapper.vm.inputValue).toBe('Новое значение');
  • find(selector) возвращает первый элемент, соответствующий селектору.
  • findAll(selector) возвращает массив всех найденных элементов.

Проверка текста и атрибутов

Для проверки содержимого и атрибутов элементов используется API wrapper:

const wrapper = mount(MyComponent, {
  props: { title: 'Vue Test' }
});

expect(wrapper.text()).toContain('Vue Test');
expect(wrapper.find('h1').attributes('id')).toBe('main-title');
  • text() возвращает весь текст внутри компонента.
  • attributes(name) позволяет проверить значение конкретного атрибута.
  • classes() возвращает массив классов элемента.

Тестирование событий и эмитирования

Компоненты Vue активно используют события ($emit). Vue Test Utils предоставляет инструменты для проверки эмитированных событий:

const wrapper = mount(MyComponent);

wrapper.vm.$emit('custom-event', 42);
expect(wrapper.emitted('custom-event')).toBeTruthy();
expect(wrapper.emitted('custom-event')[0]).toEqual([42]);
  • emitted() возвращает объект всех событий, вызванных компонентом.
  • Позволяет проверять количество вызовов и переданные аргументы.

Работа с асинхронным кодом

Vue компоненты часто используют асинхронные операции: watchers, nextTick, async methods. Для тестирования асинхронного кода важно использовать await и nextTick:

import { nextTick } from 'vue';

const wrapper = mount(MyComponent);

wrapper.vm.incrementAsync();
await nextTick();

expect(wrapper.vm.count).toBe(1);
  • nextTick() гарантирует, что все реактивные обновления завершены перед проверкой.
  • Асинхронные методы тестируются через промисы или async/await.

Использование слотов

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

const wrapper = mount(MyComponent, {
  slots: {
    default: '<span>Слот-контент</span>'
  }
});

expect(wrapper.html()).toContain('Слот-контент');
  • Можно передавать как текст, так и другие компоненты.
  • Слоты именованные (slots: { header: '<h1>Header</h1>' }) поддерживаются аналогично.

Мокинг зависимостей

Для изоляции тестов удобно подменять внешние зависимости, такие как Vuex, роутер или API:

const wrapper = mount(MyComponent, {
  global: {
    mocks: {
      $t: (msg) => msg, // мок для i18n
      $store: {
        state: { count: 0 },
        dispatch: jest.fn()
      }
    }
  }
});
  • global.mocks позволяет подменять свойства this внутри компонента.
  • global.plugins — подключение Vuex, Vue Router и других плагинов.

Полезные методы wrapper

Метод Описание
exists() Проверяет существование элемента
isVisible() Проверяет видимость элемента
html() Возвращает HTML-код компонента
setProps() Позволяет изменить пропсы после монтирования
setData() Позволяет изменить состояние data после монтирования
unmount() Размонтирует компонент и освобождает ресурсы

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


Интеграция с Jest

Vue Test Utils идеально сочетается с Jest. Пример полного теста компонента:

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

test('увеличение счетчика при клике', async () => {
  const wrapper = mount(Counter);
  const button = wrapper.find('button');

  await button.trigger('click');
  expect(wrapper.text()).toContain('1');
});
  • Асинхронные события тестируются с await.
  • expect используется для проверки состояния DOM и данных компонента.

Итог

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