Тестирование маршрутизации

Маршрутизация во Vue.js обеспечивается библиотекой Vue Router, которая управляет переходами между компонентами на основе URL. Для создания надежных приложений важно тестировать маршруты, проверяя корректность переходов, параметров маршрутов и работы навигационных охранников.

Настройка тестовой среды

Для тестирования маршрутов чаще всего используют Jest совместно с @vue/test-utils. Основные шаги настройки:

  1. Установка зависимостей:
npm install --save-dev jest @vue/test-utils vue-jest babel-jest
npm install vue-router@next
  1. Создание маршрутизатора для тестов:
import { createRouter, createWebHistory } from 'vue-router'
import Home from '@/components/Home.vue'
import About from '@/components/About.vue'

const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/about', name: 'About', component: About }
]

export function createTestRouter() {
  return createRouter({
    history: createWebHistory(),
    routes
  })
}

Тестирование переходов

Для проверки навигации используют метод push маршрутизатора и асинхронное ожидание завершения перехода:

import { mount } from '@vue/test-utils'
import { createTestRouter } from './router'
import App from '@/App.vue'

test('переход на страницу About', async () => {
  const router = createTestRouter()
  const wrapper = mount(App, {
    global: { plugins: [router] }
  })

  await router.push('/about')
  await router.isReady()

  expect(wrapper.html()).toContain('About Page')
})

Ключевой момент: всегда использовать await router.isReady() после навигации, иначе компонент может быть еще не смонтирован.

Тестирование параметров маршрута

Параметры маршрута проверяются через объект route.params. Например, динамический маршрут /user/:id:

import User from '@/components/User.vue'

const routes = [
  { path: '/user/:id', name: 'User', component: User }
]

test('маршрут с параметром id', async () => {
  const router = createRouter({ history: createWebHistory(), routes })
  const wrapper = mount(User, { global: { plugins: [router] } })

  await router.push('/user/42')
  await router.isReady()

  expect(wrapper.vm.$route.params.id).toBe('42')
})

Тестирование навигационных охранников

Навигационные охранники (beforeEach, beforeRouteEnter) позволяют контролировать доступ к маршрутам. Их поведение проверяется через мок-функции:

const mockGuard = jest.fn((to, from, next) => next())
router.beforeEach(mockGuard)

await router.push('/about')
await router.isReady()

expect(mockGuard).toHaveBeenCalled()
expect(mockGuard.mock.calls[0][0].path).toBe('/about')

Особенность: важно учитывать асинхронность охранников, особенно если внутри них используются Promise или асинхронные проверки авторизации.

Тестирование редиректов и ошибок

Маршруты могут перенаправлять пользователя на другие пути. Для их проверки используют replace и push:

const routes = [
  { path: '/login', component: Login },
  { path: '/dashboard', redirect: '/login' }
]

test('редирект на /login', async () => {
  const router = createRouter({ history: createWebHistory(), routes })
  const wrapper = mount(App, { global: { plugins: [router] } })

  await router.push('/dashboard')
  await router.isReady()

  expect(router.currentRoute.value.path).toBe('/login')
})

Для тестирования 404 страниц создается wildcard маршрут /:pathMatch(.*)* и проверяется корректный рендер компонента ошибки.

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

Если приложение использует Vuex, маршрутизация может зависеть от состояния. В тестах можно создавать мок-хранилище:

import { createStore } from 'vuex'

const store = createStore({
  state: { isAuthenticated: false },
  getters: { isAuthenticated: state => state.isAuthenticated }
})

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !store.getters.isAuthenticated) {
    next('/login')
  } else {
    next()
  }
})

Тестирование включает изменение состояния Vuex и проверку корректного редиректа.

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

  • Использовать отдельный тестовый маршрутизатор, чтобы не зависеть от реальной конфигурации приложения.
  • Проверять все возможные пути, включая редиректы и ошибки.
  • Обеспечивать асинхронное ожидание router.isReady() перед проверкой содержимого компонента.
  • Мокировать зависимости и состояние Vuex для сценариев с авторизацией.
  • Для сложных приложений полезно разделять тесты на: навигация, параметры, охранники, редиректы, ошибки.

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