Vue路由同路径不同名称如何覆盖onBeforeRouteUpdate分支测试?
解决方案
1. 覆盖if分支(路由参数变化但名称相同)
通过实际跳转同名称、不同参数的路由,验证doSomething()逻辑被触发:
import { mount } from '@vue/test-utils' import { createRouter, createWebHistory } from 'vue-router' import TestComponent from './TestComponent.vue' import { vi } from 'vitest' // 初始化路由实例 const router = createRouter({ history: createWebHistory(), routes: [ { path: '/test/:id', name: 'test', component: TestComponent } ] }) test('executes doSomething when route params change with same route name', async () => { // 针对组件内部的doSomething函数做spy(需提前通过defineExpose暴露该函数) const doSomethingSpy = vi.spyOn(TestComponent, 'doSomething') // 跳转到初始路由 router.push('/test/1') await router.isReady() const wrapper = mount(TestComponent, { global: { plugins: [router] } }) // 跳转到同名称、不同参数的路由,触发组件复用与钩子 router.push('/test/2') await router.isReady() expect(doSomethingSpy).toHaveBeenCalled() })
2. 覆盖else分支(路由名称不同)
由于跳转到不同名称的路由会直接卸载当前组件,onBeforeRouteUpdate不会自然触发,因此可以手动调用钩子的回调函数,传入名称不同的to和from路由对象:
import { mount } from '@vue/test-utils' import { createRouter, createWebHistory } from 'vue-router' import TestComponent from './TestComponent.vue' import { vi } from 'vitest' import * as vueRouter from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/test/:id', name: 'test', component: TestComponent } ] }) test('executes else branch when route name changes', async () => { // 捕获onBeforeRouteUpdate的调用,提取我们定义的回调函数 const onBeforeRouteUpdateSpy = vi.spyOn(vueRouter, 'onBeforeRouteUpdate') router.push('/test/1') await router.isReady() mount(TestComponent, { global: { plugins: [router] } }) // 从spy的调用记录中获取路由更新回调 const routeUpdateHandler = onBeforeRouteUpdateSpy.mock.calls[0][0] // 传入名称不同的路由对象,触发else分支 const to = { name: 'otherRoute' } const from = { name: 'test' } routeUpdateHandler(to, from) // 断言else分支的业务逻辑,例如如果分支内有doOtherThing(),则断言其被调用 // expect(doOtherThingSpy).toHaveBeenCalled() })
核心逻辑说明
onBeforeRouteUpdate仅在组件被复用时触发(同名称路由参数变化场景),跳转到不同名称路由时组件会被卸载,钩子无法自然执行。- 通过
vitest.spyOn捕获onBeforeRouteUpdate的调用,可直接拿到我们定义的回调函数,手动传入不同参数即可覆盖else分支。 - 若else分支有特定业务逻辑,需提前对该逻辑做spy或通过
defineExpose暴露,以便测试断言。
内容的提问来源于stack exchange,提问作者demiglace
相关产品推荐
相关产品推荐

