Tester avec Vue Router
Mise en place d’un router de test
Pour tester des composants qui dépendent de Vue Router, vous devez créer un router simulé:
import { mount } from '@vue/test-utils'import { createRouter, createWebHistory } from 'vue-router'import { describe, it, expect, beforeEach } from 'vitest'import AppNavigation from '@/components/AppNavigation.vue'import Home from '@/pages/Home.vue'import About from '@/pages/About.vue'
describe('AppNavigation.vue', () => { let router
beforeEach(() => { // Créer un router de test avec des routes simulées router = createRouter({ history: createWebHistory(), routes: [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About } ] }) })
it('highlights the current route link', async () => { // Monter le composant avec le routeur const wrapper = mount(AppNavigation, { global: { plugins: [router] } })
// Naviguer vers la route "about" await router.push('/about')
// Vérifier que le lien "about" a la classe "active" expect(wrapper.find('a[href="/about"]').classes()).toContain('active') expect(wrapper.find('a[href="/"]').classes()).not.toContain('active') })})
Mocker le routeur avec createRouterMock
Au lieu de créer un routeur complet, vous pouvez mocker uniquement les fonctionnalités dont vous avez besoin:
import { mount } from '@vue/test-utils'import { describe, it, expect, vi } from 'vitest'import ProductLink from '@/components/ProductLink.vue'
describe('ProductLink.vue', () => { it('navigates to the product page when clicked', async () => { // Mocker $router et $route const mockRouter = { push: vi.fn() } const mockRoute = { params: {} }
const wrapper = mount(ProductLink, { props: { productId: '123' }, global: { mocks: { $router: mockRouter, $route: mockRoute } } })
// Simuler un clic sur le lien await wrapper.find('.product-link').trigger('click')
// Vérifier que router.push a été appelé avec le bon chemin expect(mockRouter.push).toHaveBeenCalledWith({ name: 'product-details', params: { id: '123' } }) })})
Tester les composants avec des paramètres de route
Si votre composant utilise les paramètres de route, vous pouvez les simuler ainsi:
import { mount } from '@vue/test-utils'import { describe, it, expect } from 'vitest'import UserProfile from '@/components/UserProfile.vue'
describe('UserProfile.vue', () => { it('displays user information based on route param', () => { // Simuler un objet route avec des paramètres const mockRoute = { params: { userId: '42' } }
const wrapper = mount(UserProfile, { global: { mocks: { $route: mockRoute } } })
// Vérifier que le composant utilise le paramètre correctement expect(wrapper.text()).toContain('User ID: 42') })})
Tester les gardes de navigation
Si vous avez des composants qui utilisent des gardes de navigation, vous pouvez les tester ainsi:
import { mount } from '@vue/test-utils'import { describe, it, expect, vi, beforeEach } from 'vitest'import { createRouter, createWebHistory } from 'vue-router'import AdminPanel from '@/components/AdminPanel.vue'import LoginPage from '@/pages/LoginPage.vue'import { useAuthStore } from '@/stores/auth'import { createPinia } from 'pinia'
describe('Navigation Guards', () => { let router let pinia let authStore
beforeEach(() => { // Créer un store Pinia pinia = createPinia()
// Créer un router de test router = createRouter({ history: createWebHistory(), routes: [ { path: '/admin', name: 'admin', component: AdminPanel, meta: { requiresAuth: true } }, { path: '/login', name: 'login', component: LoginPage } ] })
// Ajouter un garde de navigation router.beforeEach((to, from) => { const auth = useAuthStore() if (to.meta.requiresAuth && !auth.isAuthenticated) { return { name: 'login' } } })
// Monter l'application avec le router et pinia mount({ template: '<router-view />', }, { global: { plugins: [router, pinia] } })
// Accéder au store d'authentification authStore = useAuthStore() })
it('redirects to login when accessing protected route as unauthenticated user', async () => { // Simuler un utilisateur non authentifié authStore.isAuthenticated = false
// Essayer d'accéder à une route protégée await router.push('/admin')
// Vérifier la redirection expect(router.currentRoute.value.name).toBe('login') })
it('allows access to protected route for authenticated users', async () => { // Simuler un utilisateur authentifié authStore.isAuthenticated = true
// Accéder à une route protégée await router.push('/admin')
// Vérifier qu'il n'y a pas de redirection expect(router.currentRoute.value.name).toBe('admin') })})
Tester les liens router-link
Pour tester les composants qui utilisent router-link
:
import { mount } from '@vue/test-utils'import { describe, it, expect, vi } from 'vitest'import MainMenu from '@/components/MainMenu.vue'import { RouterLinkStub } from '@vue/test-utils'
describe('MainMenu.vue', () => { it('renders router links with correct props', () => { const wrapper = mount(MainMenu, { global: { stubs: { RouterLink: RouterLinkStub } } })
const homeLink = wrapper.findComponent(RouterLinkStub)
// Vérifier les props du RouterLink expect(homeLink.props().to).toEqual({ name: 'home' })
// Vérifier le nombre de liens const links = wrapper.findAllComponents(RouterLinkStub) expect(links.length).toBe(3) // supposant qu'il y a 3 liens dans le menu })})