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

Vue Test Utils v2无法Mock全局route函数的问题求助

全局route函数的正确Mock方案

先明确你的全局route函数是哪种注入方式,对应不同的Mock方法:

1. 函数挂载到Vue实例(app.config.globalProperties)

如果是在app.js里通过app.config.globalProperties.$route = route挂载到全局,测试时直接在组件挂载配置里用global.mocks模拟:

import { mount } from '@vue/test-utils'
import ConversationStatus from './ConversationStatus.vue'
import { vi } from 'vitest'

describe('ConversationStatus', () => {
  it('调用全局route函数切换归档状态', () => {
    // 创建Mock函数,指定返回的路由地址
    const mockRoute = vi.fn(() => '/mock-conversation/archive')
    
    const wrapper = mount(ConversationStatus, {
      global: {
        mocks: {
          $route: mockRoute // 这里的key要和你挂载的全局属性名完全一致,比如如果是直接挂载成route就写route
        }
      }
    })

    // 触发组件的toggleArchive方法
    wrapper.vm.toggleArchive()

    // 断言Mock函数被调用
    expect(mockRoute).toHaveBeenCalled()
    // 若知道调用参数,可进一步验证:expect(mockRoute).toHaveBeenCalledWith('conversation.archive', { id: 1 })
  })
})

2. 函数挂载到window对象

如果route是挂载在window上的全局函数(比如window.route = route),直接Mockwindow上的对应属性即可:

import { mount } from '@vue/test-utils'
import ConversationStatus from './ConversationStatus.vue'
import { vi } from 'vitest'

describe('ConversationStatus', () => {
  it('调用window.route切换归档', () => {
    // 备份原函数,避免影响其他测试
    const originalRoute = window.route
    // 替换成Mock函数
    window.route = vi.fn(() => '/mock-url')

    const wrapper = mount(ConversationStatus)
    wrapper.vm.toggleArchive()

    expect(window.route).toHaveBeenCalled()

    // 测试结束后恢复原函数
    window.route = originalRoute
  })
})

3. 组件直接import route模块

如果组件里是通过import route from '@/utils/route'引入的函数,用vi.mockMock整个模块:

import { vi } from 'vitest'
// Mock目标模块,指定默认导出为Mock函数
vi.mock('@/utils/route', () => ({
  default: vi.fn(() => '/mock-path')
}))

import route from '@/utils/route'
import { mount } from '@vue/test-utils'
import ConversationStatus from './ConversationStatus.vue'

describe('ConversationStatus', () => {
  it('调用导入的route函数', () => {
    const wrapper = mount(ConversationStatus)
    wrapper.vm.toggleArchive()
    expect(route).toHaveBeenCalled()
  })
})

4. 若是Inertia.js的全局route函数

如果用的是Inertia的route辅助函数,同时要Mockrouter.visit的话:

import { vi } from 'vitest'
// Mock Inertia的route模块
vi.mock('@inertiajs/vue3', () => ({
  route: vi.fn(() => '/mock-archive')
}))

import { mount } from '@vue/test-utils'
import ConversationStatus from './ConversationStatus.vue'

describe('ConversationStatus', () => {
  it('触发route生成地址并调用router.visit', () => {
    const mockVisit = vi.fn()
    const wrapper = mount(ConversationStatus, {
      global: {
        mocks: {
          $inertia: {
            visit: mockVisit
          }
        }
      }
    })

    wrapper.vm.toggleArchive()

    expect(route).toHaveBeenCalled()
    expect(mockVisit).toHaveBeenCalledWith('/mock-archive')
  })
})

常见问题排查

  • 确保Mock的属性名和全局注入的名称完全一致(比如是$route还是route)
  • 若用vi.mock,模块路径要和组件里导入的路径完全匹配
  • 测试后记得清理Mock(比如恢复window上的原函数),避免污染其他测试用例

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:10:59