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 { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
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
文件,并添加以下内容:
// 在 Next.js 应用外部直接使用 useRouter 会触发 "NextRouter was not mounted" 错误。
// 为了解决这个问题,我们通过模拟(mock)来劫持 useRouter 方法,并提供必要的国际化数据。
import { beforeEach, vi } from "vitest";
import "@testing-library/jest-dom";
import * as nextRouter from "next/router";
import type { NextRouter } from "next/router";
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 { describe, it } from 'vitest'
import { createI18n } from 'next-international'
import { render, screen, waitFor } from './customRender'
import en from '../locales/messages/enUS'
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