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

如何使用Vitest测试Quasar中关联路由与Vue i18n的boot文件?

用Vitest测试Quasar i18n Boot文件的方案

1. 前置准备

  • 确保项目已安装vitest、@vue/test-utils、vue-router及Quasar测试相关依赖
  • 在vitest.config.js中配置Quasar环境支持,比如引入@quasar/vite-plugin

2. 编写测试用例

测试文件路径建议为tests/boot/i18n.spec.js,核心测试点包括:

  • 验证i18n实例是否正确挂载到Vue应用
  • 确认Quasar的Lang模块被设置为默认语言包
  • 检查路由前置钩子是否注册成功,且guessLocale被正确调用

测试代码示例

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { createApp } from 'vue'
import { createRouter, createMemoryHistory } from 'vue-router'
import i18nBoot from 'src/boot/i18n'
import { i18nBootConfig, qDefaultLangPack } from 'src/i18n/config'
import { guessLocale } from 'src/helpers/lang'
import { Lang } from 'quasar'

// 模拟外部依赖
vi.mock('src/i18n/config', () => ({
  i18nBootConfig: { locale: 'en' },
  qDefaultLangPack: { en: {} }
}))

vi.mock('src/helpers/lang', () => ({
  guessLocale: vi.fn().mockResolvedValue()
}))

vi.mock('quasar', () => ({
  Lang: { set: vi.fn() }
}))

describe('i18n boot 文件', () => {
  let app
  let router

  beforeEach(() => {
    // 创建测试用Vue实例和内存路由
    app = createApp({})
    router = createRouter({
      history: createMemoryHistory(),
      routes: [{ path: '/', component: { template: '<div></div>' } }]
    })

    // 重置所有mock状态
    vi.clearAllMocks()
  })

  it('应该将i18n实例挂载到Vue应用', async () => {
    await i18nBoot({ app, router, ssrContext: null })
    expect(app._context.plugins.some(p => p.name === 'vue-i18n')).toBe(true)
  })

  it('应该设置Quasar Lang为默认语言包', async () => {
    await i18nBoot({ app, router, ssrContext: null })
    expect(Lang.set).toHaveBeenCalledWith(qDefaultLangPack)
  })

  it('应该注册路由前置钩子并调用guessLocale', async () => {
    const beforeEachSpy = vi.spyOn(router, 'beforeEach')
    
    await i18nBoot({ app, router, ssrContext: null })
    
    // 验证路由钩子已注册
    expect(beforeEachSpy).toHaveBeenCalled()

    // 模拟路由跳转触发钩子
    await router.push('/')
    
    // 验证guessLocale的调用参数正确
    expect(guessLocale).toHaveBeenCalledWith(expect.objectContaining({
      route: expect.any(Object),
      ssrContext: null
    }))
  })

  it('当传入ssrContext时,应该传递给guessLocale', async () => {
    const mockSsrContext = { req: {} }
    await i18nBoot({ app, router, ssrContext: mockSsrContext })
    
    await router.push('/')
    
    expect(guessLocale).toHaveBeenCalledWith(expect.objectContaining({
      ssrContext: mockSsrContext
    }))
  })
})

3. 核心测试技巧

  • 用vi.mock模拟外部依赖,隔离测试逻辑,避免受外部模块影响
  • 使用内存路由createMemoryHistory模拟路由环境,无需真实浏览器
  • 通过spyOn监听路由的beforeEach方法,确认钩子注册行为
  • 模拟路由跳转触发前置钩子,验证guessLocale的调用逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:41:18