You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:40:02