🧪 Testing Nuxt I18n Micro Module
📖 Introduction to Testing
Testing the Nuxt I18n Micro module is crucial to ensure that your application's localization features work as expected. This documentation will guide you through setting up the testing environment, creating mock configurations for vitest, and writing tests for your components. For a practical example, you can refer to the example project on GitHub.
See Testing routing strategies for how this repository runs its own suites — the unit / integration / e2e Vitest projects, the per-strategy files (test/strategies-*.test.ts), and generate regressions.
🛠️ Setting Up the Testing Environment
1. Install @i18n-micro/test-utils
npm install @i18n-micro/test-utils --save-dev2. Create a Mock Configuration File
Prefer setupNuxtI18nMock — isolated state, optional factory seeds, and auto-beforeEach reseed. Keep mockNuxtImport in this file so @nuxt/test-utils can transform it:
// tests/unit-setup.ts
import { setupNuxtI18nMock } from '@i18n-micro/test-utils'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
import { beforeEach, vi } from 'vitest'
const { i18n, useI18n, setTranslationsFromJson } = setupNuxtI18nMock({
spy: vi.fn,
beforeEach,
// optional: translations: { welcome: 'Welcome' },
})
mockNuxtImport('useI18n', () => useI18n)
export { i18n, setTranslationsFromJson }createFakeI18n({ spy, translations, strategy, isolated }) remains available for lower-level setups. Pass { spy: vi.fn } for Vitest spies; omit spy for plain functions.
3. Configure Vitest
// vitest.config.ts
import { defineVitestConfig } from '@nuxt/test-utils/config'
export default defineVitestConfig({
test: {
watch: false,
setupFiles: ['./tests/unit-setup.ts'],
include: ['./**/*.spec.ts'],
},
})🧪 Writing Tests
Example Component
<script setup lang="ts">
const { $t } = useI18n()
const props = defineProps({
message: {
type: String,
default: null,
},
})
// Test to see that $t works in script setup as well as the template
const message = props.message || $t('defaultMessage')
</script>
<template>
<div>
<p>Test from component: {{ $t('welcome') }}</p>
<p data-testid="message">Test message from props: {{ message }}</p>
</div>
</template>Test File
// tests/unit/example.spec.ts
import { describe, it, expect, beforeEach } from 'vitest'
import { mount } from '@vue/test-utils'
import ExampleComponent from '@/components/ExampleComponent.vue'
import fs from 'fs'
import path from 'path'
import { setTranslationsFromJson } from './unit-setup'
describe('ExampleComponent', () => {
beforeEach(async () => {
const fileContent = fs.readFileSync(path.join(__dirname, '../../locales/en-GB.json')).toString()
await setTranslationsFromJson('en', JSON.parse(fileContent))
})
it('renders the welcome message correctly', () => {
const wrapper = mount(ExampleComponent)
expect(wrapper.text()).toContain('Test from component: Welcome')
})
it('renders the default message correctly', () => {
const wrapper = mount(ExampleComponent)
expect(wrapper.find('[data-testid="message"]').text()).toContain('Test message from props: Default Message')
})
it('renders the custom message correctly', () => {
const wrapper = mount(ExampleComponent, {
props: {
message: 'Custom Message',
},
})
expect(wrapper.find('[data-testid="message"]').text()).toContain('Test message from props: Custom Message')
})
})📝 Best Practices for Testing
- 🔧 Mock i18n Functions: Prefer
setupNuxtI18nMock+mockNuxtImport('useI18n', () => useI18n). - ♻️ Isolation: The harness uses a private cache; for shared helpers call
resetI18n()inbeforeEach. - ⚙️ Use Vitest for Unit Tests: Pair with
@nuxt/test-utils(mountSuspended/renderSuspended) or@vue/test-utils. - 📚 Document Your Tests: Clearly document the purpose and expected outcomes of each test.
📊 i18n Utility Methods
Below is a table describing the main helpers from @i18n-micro/test-utils.
| Method | Description |
|---|---|
setupNuxtI18nMock(options?) | Isolated fake + useI18n factory; pass beforeEach to auto-reseed. |
createIsolatedFakeI18n(options?) | Isolated fake without Nuxt wiring. |
createI18nTestContext(options?) | Low-level context (t, path stubs, createFake). |
resetI18n(options?) | Clears the shared translation cache and restores default locale state. |
createFakeI18n({ spy?, translations?, strategy?, … }) | Builds a useI18n()-shaped mock ($t + t + helper). |
t(key, params, defaultValue) | Translates a key with optional parameters and a default value. |
tc(key, params, defaultValue) | Translates a key with pluralization support. |
_t(route) / _ts(route) | Bind t / ts to another route name ($_t / $_ts). |
setTranslationsFromJson(locale, translations) | Loads translations from a JSON object for a specific locale. |
loadPageTranslations(locale, routeName, translations) | Loads a page-specific dictionary chunk. |
setMissingHandler(handler) | Callback for unresolved keys (null to clear). |
getLocale() / setLocale(val) | Read / set the current locale. |
getLocaleName() / setLocaleName(val) | Read / set the current locale display name. |
getLocales() / setLocales(val) | Read / set the locale list. |
defaultLocale() / setDefaultLocale(val) | Read / set the default locale. |
getRouteName() | Returns the current route name used for page translations. |
setRouteName(val) | Sets the route name (settRouteName kept as a typo alias). |
ts(key, params, defaultValue) | Translates a key and returns the result as a string. |
tn(value, options?) | Formats a number with inline Intl.NumberFormatOptions. |
td(value, options?) | Formats a date with inline Intl.DateTimeFormatOptions. |
tdr(value, options?) | Formats a relative time with Intl.RelativeTimeFormat. |
has(key) | Checks if a translation key exists. |
resolveTranslations() | Returns the active translation tree for the current locale and route. |
setTranslation(key, value) | Replaces the value at key in the active dictionary (replace, not merge). |
mergeTranslations(newTranslations) | Merges translations into the active locale at runtime. |
localePath(to, locale?) | Prefix stub: '/en/about' (respects strategy; no real vue-router). |
switchLocalePath(locale) | Stub path for the last localePath target — does not change locale. |
By following these steps, you can effectively test the Nuxt I18n Micro module and ensure that your application's localization features work as expected.