При тестировании компонентов Vue, которые зависят от маршрутизации,
критически важно корректно настроить экземпляр маршрутизатора.
Vue Router в сочетании с Vue Test Utils
позволяет создавать локальные маршрутизаторы, имитировать навигацию и
проверять поведение компонентов при смене маршрутов.
Для начала подключаются основные библиотеки:
import { createRouter, createWebHistory } from 'vue-router';
import { mount } from '@vue/test-utils';
import ComponentUnderTest from '@/components/ComponentUnderTest.vue';
createRouter — функция для создания экземпляра
маршрутизатора.createWebHistory — стратегия истории браузера для
маршрутов.mount — метод из Vue Test Utils для
монтирования компонентов в тестах.Для тестов не рекомендуется использовать основной роутер приложения. Вместо этого создается отдельный экземпляр:
const routes = [
{ path: '/', name: 'Home', component: { template: '<div>Home</div>' } },
{ path: '/about', name: 'About', component: { template: '<div>About</div>' } },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
Особенности:
routes содержит только маршруты, необходимые для
теста.template: '<div>...</div>') для ускорения
тестирования.history) не обязательно должна совпадать с
основной; для юнит-тестов подойдет createMemoryHistory для
имитации истории без влияния на браузер.Прямое монтирование компонента без инициализации маршрутизатора
приведет к ошибкам при доступе к $router или
$route. Важно сначала выполнить
router.isReady():
await router.isReady();
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [router],
},
});
Пояснение:
router.isReady() гарантирует, что начальный маршрут
корректно загружен.global.plugins передает роутер в контекст
компонента так же, как он используется в приложении.Для проверки навигации можно использовать метод
router.push:
await router.push('/about');
await wrapper.vm.$nextTick();
expect(wrapper.html()).toContain('About');
Ключевые моменты:
router.push изменяет маршрут программно.await wrapper.vm.$nextTick() нужен для обновления DOM
после изменения маршрута.wrapper.html() или wrapper.text().Иногда требуется проверить реакцию компонента на параметры:
await router.push({ name: 'About', query: { ref: 'test' } });
await wrapper.vm.$nextTick();
expect(wrapper.vm.$route.query.ref).toBe('test');
$route.params используется для динамических сегментов
пути (/user/:id).$route.query хранит query-параметры, например
?ref=test.Для крупных тестов удобно создавать функцию-фабрику:
function createTestRouter(initialRoute = '/') {
const routes = [
{ path: '/', name: 'Home', component: { template: '<div>Home</div>' } },
{ path: '/about', name: 'About', component: { template: '<div>About</div>' } },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
router.push(initialRoute);
return router;
}
<router-link> и
<router-view>Vue Test Utils корректно обрабатывает
<router-view> и <router-link> при
подключении локального маршрутизатора:
const wrapper = mount(ComponentUnderTest, {
global: {
plugins: [router],
},
});
const link = wrapper.findComponent({ name: 'RouterLink' });
await link.trigger('click');
expect(router.currentRoute.value.path).toBe('/about');
<router-link> можно имитировать кликом
через trigger('click').router.currentRoute.value.createMemoryHistory для ускорения и
изоляции.Если требуется, можно расширять фабрики для включения асинхронных маршрутов, lazy-loading компонентов и глобальных guard-ов. Это позволяет тестировать сложные сценарии навигации, авторизации и условного рендеринга компонентов на основе маршрутов.