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

如何在Vue3/Nuxt3 Composition API中用Vitest Mock i18n的t()函数?

解决Nuxt3/Vue3中Vitest Mock useI18n的$setup.t is not a function错误

问题根源

你当前的测试代码同时混用了三种mock方式(vi.mock('vue-i18n')、mockNuxtImport('useI18n')、全局mocks),导致mock逻辑冲突。另外,Nuxt3项目中useI18n是从@nuxtjs/i18n包导出的,而非vue-i18n,这也是mock失效的核心原因之一。

正确解决方案

方案1:使用mockNuxtImport(Nuxt官方推荐)

这是最适配Nuxt3的mock方式,直接mock Nuxt的useI18n导入:

import { shallowMount } from '@vue/test-utils'
import Overview from './[...slug].vue'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
import { vi } from 'vitest'

// 正确mock Nuxt的useI18n
mockNuxtImport('useI18n', () => {
  return vi.fn(() => ({
    t: (key) => key, // 直接返回key作为翻译结果
    locale: ref('en')
  }))
})

describe('overview page', () => {
  let wrapper

  it('is a Vue instance', () => {
    wrapper = shallowMount(Overview, {
      global: {
        // 不需要额外的全局mock,mockNuxtImport已经处理了useI18n
      }
    })
    expect(wrapper.vm).toBeTruthy()
  })
})

方案2:全局mock $t(适配模板直接调用的场景)

如果你想通过全局mock解决,需要注意:<script setup>中解构的t不会自动挂载到组件实例(vm)上,模板中直接使用t()时,需要确保全局有可用的$t,或者修改组件把t暴露给模板:

组件修改(可选)

在<script setup>中添加:

// 把t暴露给模板,这样模板可以直接用t
defineExpose({ t })

测试代码修改

import { shallowMount } from '@vue/test-utils'
import Overview from './[...slug].vue'
import { vi } from 'vitest'

describe('overview page', () => {
  let wrapper

  it('is a Vue instance', () => {
    wrapper = shallowMount(Overview, {
      global: {
        mocks: {
          $t: (key) => key // 全局mock $t,模板中可以使用$t()
        }
      }
    })
    expect(wrapper.vm).toBeTruthy()
  })
})

注意:这种方式需要把组件模板中的t('xxx')改成$t('xxx'),或者按上面的方式把t暴露给模板。

关键注意事项

  • 不要同时混用多种mock方式,选择一种即可,避免冲突。
  • Nuxt3的useI18n来自@nuxtjs/i18n,不是vue-i18n,mock时要对应正确的包名。
  • <script setup>中的变量默认是私有的,模板中直接使用解构的t时,要么确保useI18n的mock正确注入,要么通过defineExpose暴露变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:03:10