В Vue-приложениях отделение бизнес-логики от пользовательского интерфейса является ключевым аспектом для упрощения тестирования и повышения поддерживаемости кода. Vue Test Utils предоставляет инструменты для изоляции компонентов и проверки их поведения без зависимости от конкретного DOM или внешних библиотек.
Компоненты Vue можно разделить на два типа: презентационные и умные (контейнерные).
Такое разделение упрощает тестирование:
shallowMount и mountshallowMount создаёт обёртку компонента без рендеринга
дочерних компонентов, что позволяет сосредоточиться на логике текущего
компонента:
import { shallowMount } from '@vue/test-utils';
import UserProfile from '@/components/UserProfile.vue';
test('проверка рендеринга имени пользователя', () => {
const wrapper = shallowMount(UserProfile, {
props: { name: 'Иван' }
});
expect(wrapper.text()).toContain('Иван');
});
mount используется для полного рендеринга, включая
дочерние компоненты. Он актуален, когда необходимо проверить
взаимодействие между компонентами.
Бизнес-логику можно вынести в методы, вычисляемые свойства или отдельные сервисы, чтобы тесты не зависели от DOM.
Пример вынесенной функции:
// services/userService.js
export function formatUserName(user) {
return `${user.lastName} ${user.firstName}`;
}
Тестирование такой функции полностью отделено от компонента:
import { formatUserName } from '@/services/userService';
test('корректное форматирование имени пользователя', () => {
const user = { firstName: 'Иван', lastName: 'Петров' };
expect(formatUserName(user)).toBe('Петров Иван');
});
Vue Test Utils позволяет тестировать эмиты событий, что особенно важно для презентационных компонентов:
const wrapper = shallowMount(ButtonComponent);
wrapper.trigger('click');
expect(wrapper.emitted()).toHaveProperty('click');
Эти тесты проверяют только поведение компонента без привязки к сложному DOM или внешним зависимостям.
Изоляция логики достигается с помощью моков и стабов. Например, если компонент обращается к Vuex или API, можно заменить реальные зависимости фиктивными:
const $store = {
state: { count: 5 },
commit: jest.fn()
};
const wrapper = shallowMount(Counter, {
global: { mocks: { $store } }
});
wrapper.find('button').trigger('click');
expect($store.commit).toHaveBeenCalledWith('increment');
Это позволяет проверить реакцию компонента на изменения состояния без реальной интеграции с Vuex.
Вычисляемые свойства и методы должны быть протестированы отдельно от DOM:
const wrapper = shallowMount(UserProfile, {
props: { firstName: 'Иван', lastName: 'Петров' }
});
expect(wrapper.vm.fullName).toBe('Иван Петров');
wrapper.vm.updateName('Алексей');
expect(wrapper.vm.fullName).toBe('Алексей Петров');
Такой подход делает тесты быстрыми и надёжными, так как они не зависят от рендера и стилей.
Эффективное тестирование Vue-компонентов достигается комбинированием:
shallowMount для презентационных компонентовЭто создаёт чистую архитектуру тестов: каждый тест фокусируется на одной ответственности, упрощая поддержку и обнаружение ошибок.
Отделение логики от UI не только ускоряет тестирование, но и повышает повторное использование компонентов, делая код более модульным и предсказуемым.