Next.js 与 Vitest 结合 next-international 的国际化单元测试编写指北
May 14·2 min
AI 生成的摘要
本文介绍了如何使用 Vitest 进行 Next.js 应用的国际化单元测试。首先,安装 Vitest 及其依赖,并配置 vitest.config.ts 文件。接着,在项目根目录创建 vitestSetup.ts 文件,模拟 useRouter 方法以提供国际化数据。然后,编写单元测试文件 demo.test.tsx,使用 next-international 创建 I18nProvider 并渲染组件进行测试。最后,通过运行 pnpm run test 命令执行单元测试。
next-international 简介
next-international 是 Next.js 的众多国际化框架之一,因其 100% 类型安全和简单配置而受到青睐。本文不涉及 next-international 的配置,如需了解,请参考官方文档。
安装与配置
1. 安装Vitest
安装 Vitest 及其依赖:
pnpm install -D vitest @vitejs/plugin-react jsdom @testing-library/react
在项目根目录创建 vitest.config.ts
文件,并添加以下配置:
vitest.config.ts
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vitest/config'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./vitestSetup.ts']
}
})
更新 package.json 文件,添加测试命令:
package.json
{
"scripts": {
"test": "vitest"
}
}
在 tsconfig.json 文件中添加类型定义:
tsconfig.json
{
"compilerOptions": {
"types": ["@testing-library/jest-dom"]
}
}
2. 配置Vitest
在项目根目录创建 vitestSetup.ts
文件,并添加以下内容:
import type { NextRouter } from 'next/router'
import * as nextRouter from 'next/router'
// 在 Next.js 应用外部直接使用 useRouter 会触发 "NextRouter was not mounted" 错误。
// 为了解决这个问题,我们通过模拟(mock)来劫持 useRouter 方法,并提供必要的国际化数据。
import { beforeEach, vi } from 'vitest'
import '@testing-library/jest-dom'
beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
vi.spyOn(nextRouter, 'useRouter').mockImplementationOnce(
() =>
({
query: 'Mock_Vitest',
locale: 'en',
defaultLocale: 'en',
locales: ['en']
}) as unknown as NextRouter
)
})
afterEach(() => {
vi.clearAllMocks()
})
3. 编写单元测试文件
在项目根目录的 test 文件夹下创建 demo.test.tsx
文件,并添加以下内容:
demo.test.tsx
import { createI18n } from 'next-international'
import { describe, it } from 'vitest'
import en from '../locales/messages/enUS'
import { render, screen, waitFor } from './customRender'
describe('Example test', () => {
it('just an example', async () => {
const { useI18n, I18nProvider } = createI18n({
en: () => import('../locales/messages/enUS'),
})
function App() {
const t = useI18n()
return <p>{t('Hello')}</p>
}
render(
<I18nProvider locale={en}>
<App />
</I18nProvider>
)
await waitFor(() => {
expect(screen.getByText('Hello')).toBeInTheDocument()
})
})
})
4. 进行单元测试
在终端运行以下命令以执行单元测试:
pnpm run test
完成以上步骤后,即可实现基于国际化的单元测试。
最后修改时间: Aug 30