【翻译】如何使用测试库和 Vitest 测试 Vue Router 组件

本指南将向你展示如何使用真实的路由集成来测试 Vue Router 组件,并使用 mock 进行隔离组件测试。您将学习验证路由-链路交互、编程导航和导航守卫处理。

原文地址:How to Test Vue Router Components with Testing Library and Vitest

作者是Alex,德国程序员,写了很多优质的文章,专注于Vue,AI和GraphQL等前沿技术。你可以点击下面的链接访问他的博客,获取更多优质内容。
Alexander Opalic
Alexander OpalicAlex
Alex

Alex

alexop.dev
9/24/2025

德国程序员,写了很多优质的文章,专注于Vue,AI和GraphQL等前沿技术。

要学习一些项目架构方面的知识,可以关注他的文章

ヾ(•ω•`)o
让我们开始这次精彩的阅读吧!


介绍

现代 Vue 应用程序需要全面测试,以确保可靠的导航和组件性能。我们将介绍使用 测试库和 Vitest 的测试策略,通过路由集成和组件隔离来模拟真实场景。

使用测试库和Vitest 进行 Vue Router 的测试技术

让我们探索如何使用真实路由实例和模拟为 Vue Router 组件编写有效的测试。

测试 Vue Router 导航组件

导航组件示例

NavigationMenu.vuevue
<script setup lang="ts">
import { useRouter } from 'vue-router'

const router = useRouter()
function goToProfile() {
    router.push('/profile')
}
</script>

<template>
    <nav>
        <router-link to="/dashboard" class="nav-link">
            Dashboard
        </router-link>
        <router-link to="/settings" class="nav-link">
            Settings
        </router-link>
        <button @click="goToProfile">
            Profile
        </button>
    </nav>
</template>

真正的路由集成测试

使用真实的路由器实例测试完整的路由行为:

模拟路由测试

使用 router mock 隔离测试组件

ts
import type { Router } from 'vue-router';

import userEvent from '@testing-library/user-event'
import { render, screen } from '@testing-library/vue'
import { describe, expect, it, vi } from 'vitest'
import { useRouter } from 'vue-router'

import NavigationMenu from '../NavigationMenu..vue'

const mockPush = vi.fn()
vi.mock('vue-router', () => ({
    useRouter: vi.fn(),
}))

describe('NavigationMenu with mocked router', () => {
    it('should handle navigation with mocked router', async () => {
        const mockRouter = {
            push: mockPush,
            currentRoute: { value: { path: '/' } },
        } as unknown as Router

        vi.mocked(useRouter).mockImplementation(() => mockRouter)

        const user = userEvent.setup()
        render(NavigationMenu)

        await user.click(screen.getByText('Profile'))
        expect(mockPush).toHaveBeenCalledWith('/profile')
    })
})

创建一个 RouterLink Stub来测试没有 RouterLink 行为的导航

在测试中使用 RouterLinkStub:

测试导航守卫

通过在路由上下文渲染组件来测试导航守卫

vue
<script setup lang="ts">
import { onBeforeRouteLeave } from 'vue-router'

onBeforeRouteLeave(() => {
    return window.confirm('Do you really want to leave this page?')
})
</script>

<template>
    <div>
        <h1>Route Leave Guard Demo</h1>
        <div>
            <nav>
                <router-link to="/">
                    Home
                </router-link> |
                <router-link to="/about">
                    About
                </router-link> |
                <router-link to="/guard-demo">
                    Guard Demo
                </router-link>
            </nav>
        </div>
    </div>
</template>

测试导航守卫

可复用的路由测试帮助函数

创建一个辅助函数来简化路由设置

在测试中使用助手:

ts
describe('NavigationMenu', () => {
    it('should navigate using router links', async () => {
        const { router } = renderWithRouter(NavigationMenu, {
            initialRoute: '/',
        })

        await router.isReady()
        const user = userEvent.setup()

        await user.click(screen.getByText('Dashboard'))
        expect(router.currentRoute.value.path).toBe('/dashboard')
    })
})

结论:Vue Router 组件测试的最佳实践

当我们测试依赖于路由的组件时,我们需要考虑是否要在最真实的用例中测试功能,还是单独测试。在我看来,模拟测试越多,测试结果就越糟糕。我个人的建议是尽量使用真正的路由,而不是模拟它。有时,也会有例外,所以请记住这一点。

此外,您可以通过专注于不依赖路由功能的组件来帮助自己。为视图/页面组件保留路由逻辑。在保持组件简单的同时,我们永远不会遇到模拟路由的问题。

【翻译】如何使用 Vitest 在 Vue 中进行视觉回归测试?
编程学习网站

评论区

评论加载中...