Vue Test Utils (VTU) предоставляет API для изоляции компонентов и тестирования их поведения. Перед началом тестирования необходимо корректно настроить окружение, учитывая платформу — браузер или сервер (Node.js). Для браузерного тестирования часто используется jsdom, который эмулирует DOM, что позволяет запускать тесты в Node.js без реального браузера. В средах вроде Node.js конфигурация отличается, так как DOM отсутствует по умолчанию.
Пример базовой конфигурации с Jest и jsdom:
import { config } from '@vue/test-utils';
import { beforeEach } from '@jest/globals';
beforeEach(() => {
config.global.stubs = {};
config.global.mocks = {};
});
Здесь stubs используется для замены дочерних компонентов
заглушками, а mocks — для внедрения глобальных объектов,
таких как $router или $store. Для серверного
тестирования необходимо учитывать, что асинхронные методы жизненного
цикла компонента (например, mounted) могут вести себя
иначе, поэтому тесты должны корректно ожидать их завершения.
Vue Test Utils позволяет задавать глобальные параметры для всех тестов, включая:
$route, $store, $t.Пример расширенной глобальной конфигурации:
import { config } from '@vue/test-utils';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
config.global.plugins = [new Vuex.Store({}), new VueRouter()];
config.global.stubs = ['ChildComponent'];
config.global.mocks = {
$t: (msg) => msg,
};
config.global.directives = {
focus: {
mounted(el) {
el.focus();
},
},
};
Такой подход обеспечивает единообразие тестовой среды независимо от конкретного теста, облегчает поддержку и уменьшает дублирование кода.
В Node.js отсутствует нативный DOM, что требует дополнительных шагов:
Установка jsdom:
npm install jsdom --save-devСоздание глобального DOM:
import { JSDOM } from 'jsdom';
const dom = new JSDOM('<!doctype html><html><body></body></html>');
global.window = dom.window;
global.document = dom.window.document;
global.navigator = { userAgent: 'node.js' };Настройка Vue Test Utils для Node.js:
import { config } from '@vue/test-utils';
config.global.stubs = ['router-link'];Это позволяет компонентам, которые используют браузерные API
(window, document), корректно работать в
тестовой среде.
Браузер:
click,
input, focus.Node.js:
await nextTick() или flushPromises().mount и shallowMountВыбор между mount и shallowMount зависит от
платформы и цели теста:
mount — полное рендеринг компонента с дочерними
компонентами. Предпочтительно в интеграционных тестах.shallowMount — замещает дочерние компоненты заглушками,
что ускоряет тестирование и снижает зависимость от внешних
компонентов.Пример адаптации под Node.js:
import { shallowMount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';
const wrapper = shallowMount(MyComponent, {
global: {
mocks: { $store: { state: {} } },
},
});
На всех платформах необходимо учитывать асинхронность:
await wrapper.vm.$nextTick() для ожидания
обновлений DOM.flushPromises() для ожидания завершения всех
промисов.import { flushPromises } from '@vue/test-utils';
await flushPromises();
expect(wrapper.text()).toContain('Загружено');
Конфигурация платформы должна учитывать запуск тестов в автоматизированных пайплайнах:
Если библиотека должна работать и в браузере, и на сервере:
global.mocks и
global.stubs.if (typeof window !== 'undefined') {
config.global.plugins.push(browserSpecificPlugin);
} else {
config.global.plugins.push(serverSpecificPlugin);
}
Такой подход позволяет писать тесты, которые корректно выполняются на разных платформах без модификации кода компонентов.