使用 Next.js 设置 Jest 完成单元测试

背景

Jest 和 React 测试库经常一起用于单元测试和快照测试。本指南将向您展示如何使用 Next.js 设置 Jest 并编写您的第一个测试。

快速开始

您可以将 create-next-app 与 Next.js with-jest 示例结合使用来快速入门:

1
npx create-next-app@latest --example with-jest with-jest-app

手动设置

要设置 Jest,请安装 jest 和以下软件包作为开发依赖项:

1
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

通过运行以下命令生成基本的 Jest 配置文件:

1
npm init jest@latest

这将引导您完成一系列提示,为您的项目设置 Jest,包括自动创建 jest.config.ts|js 文件。更新您的配置文件以使用 next/jest 。该转换器具有 Jest 与 Next.js 配合使用所需的所有配置选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import type { Config } from 'jest'
import nextJest from 'next/jest.js'

const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './',
})

// Add any custom config to be passed to Jest
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config)

在后台, next/jest 会自动为您配置 Jest,包括:

  • 使用 Next.js 编译器设置 transform
  • 自动模拟样式表( .css 、 .module.css 及其 scss 变体)、图像导入和 next/font
  • 将 .env (和所有变体)加载到 process.env 中
  • 从测试解析和转换中忽略 node_modules
  • 从测试解析中忽略 .next
  • 加载启用 SWC 转换的标志的 next.config.js

将测试脚本添加到 package.json

最后,将 Jest test 脚本添加到您的 package.json 文件中:

1
2
3
4
5
6
7
8
9
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "jest",
"test:watch": "jest --watch"
}
}

jest --watch 将在文件更改时重新运行测试。有关更多 Jest CLI 选项,请参阅 Jest 文档。

创建您的第一个测试:

您的项目现在已准备好运行测试。在项目的根目录中创建一个名为 __tests__ 的文件夹。

例如,我们可以添加一个测试来检查 <Page /> 组件是否成功呈现标题:

1
2
3
4
5
6
7
8
9
10
import Link from 'next/link'

export default function Home() {
return (
<div>
<h1>Home</h1>
<Link href="/about">About</Link>
</div>
)
}

**tests**/page.test.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import Page from '../app/page'

describe('Page', () => {
it('renders a heading', () => {
render(<Page />)

const heading = screen.getByRole('heading', { level: 1 })

expect(heading).toBeInTheDocument()
})
})

(可选)添加快照测试来跟踪组件中的任何意外更改:

__tests__/snapshot.js __测试__/snapshot.js

1
2
3
4
5
6
7
import { render } from '@testing-library/react'
import Page from '../app/page'

it('renders homepage unchanged', () => {
const { container } = render(<Page />)
expect(container).toMatchSnapshot()
})

运行你的测试

运行以下命令来运行测试:

1
npm run test

请我喝杯咖啡吧~

支付宝
微信