😇
【Next.js14】Jestを使ってnext/linkのテストを作成する
はじめに
next/link
のテストを作成するのが難しかったのでまとめます。
サンプルコードを使ってJestの導入からnext/link
のテスト作成まで解説していくので、興味があれば読んでいってください。
next/link
のテストを作成する
Jestを使ってプロジェクトを作成する
まずはプロジェクトを作成します。
アプリ名などはお好きにどうぞ。今回はすべて誘導されるがままに選択していきました。
$ npx create-next-app@latest
✔ What is your project named? … my-app
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
Creating a new Next.js app in /Users/tsukadaryou/my-app.
Using npm.
Initializing project with template: app-tw
Installing dependencies:
- react
- react-dom
- next
Installing devDependencies:
- typescript
- @types/node
- @types/react
- @types/react-dom
- postcss
- tailwindcss
- eslint
- eslint-config-next
added 360 packages, and audited 361 packages in 28s
134 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created my-app at /Users/tsukadaryou/my-app
Success!
の文字が確認できたら起動してみましょう。
$ yarn dev
画像のような画面が表示されれば成功です。
※上記の画像ではダークモードが適用されています
Next.jsのデフォルトの表示はとてもかっこいいのですが、分かりにくいので余分な要素は削除していきます。
app/page.tsx
export default function Home() {
return (
<main className="flex flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Jestでnext/linkをテストする</h1>
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold mt-5 py-2 px-4 rounded">
Button
</button>
</main>
);
}
テストに必要な準備をする
最初に必要なパッケージをインストールしていきましょう。
$ yarn add --dev jest @testing-library/react @testing-library/jest-dom next-router-mock ts-node @types/jest @testing-library/user-event
インストールしたパッケージのリストは以下のテーブルにまとめておきます。
package | 概要 | URL |
---|---|---|
@testing-library/react |
Reactコンポーネントを扱うテストライブラリ | https://testing-library.com/docs/react-testing-library/intro/ |
@testing-library/jest-dom |
DOM要素をマッチングするためにライブラリ | https://testing-library.com/docs/ecosystem-jest-dom/ |
next-router-mock |
URLの状態をメモリに保存できる(パスに書き込むことは不可) | https://www.npmjs.com/package/next-router-mock |
ts-node |
Node.js上でTypeScriptを実行するためのライブラリ | https://www.npmjs.com/package/ts-node |
@types/jest |
Jestで型定義をできる | https://www.npmjs.com/package/@types/jest |
@testing-library/user-event |
ブラウザ上のイベントを趣味レーションする | https://testing-library.com/docs/user-event/v13/ |
次はJestに必要なファイルを作成して、設定を書いていきます。
$ touch jest.config.ts jest.setup.ts
jest.config.ts
import type { Config } from 'jest'
import nextJest from 'next/jest'
const createJestConfig = nextJest({
dir: './',
})
const config: Config = {
coverageProvider: 'v8',
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['./jest.setup.ts']
}
export default createJestConfig(config)
jest.setup.ts
import '@testing-library/jest-dom'
これで準備は完了です!
Link
と遷移先のページを作成
まずはHome
にLink
を追加して、これから作成するsample
に遷移できるようにします。
page.tsx
+ import Link from "next/link";
export default function Home() {
return (
<main className="flex flex-col items-center justify-between p-24">
<h1 className="text-4xl font-bold">Jestでnext/linkをテストする</h1>
+ <Link href="/sample">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold mt-5 py-2 px-4 rounded">
Button
</button>
+ </Link>
</main>
);
}
次に`sample`を作っていきます。
```bash
$ mkdir sample
$ cd sample
$ touch page.tsx
app/sample/page.tsx
export default function sample() {
return (
<>
<h2 className="text-center text-4xl font-bold">Sample</h2>
</>
)
}
これでLink
を使ったページ遷移の機能は実装できました。
それではこのページ遷移機能が正しく動いているのかを確認するためのテストを作成していきます。
テスト実装
まずはテストが正しく動くかを確認します。
./page.tsx
をレンダリングするところから確認していきます。
page.test.tsx
import Page from './page';
import { render } from '@testing-library/react';
describe('Page', () => {
test ('should render without crashing', () => {
render(<Page />);
});
})
問題なければ以下のようにパスするはずです。
$ yarn test
yarn run v1.22.22
$ jest
PASS app/page.test.tsx
Page
✓ should render without crashing (20 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.817 s
Ran all test suites.
✨ Done in 4.32s.
次にLink
を使ったページ遷移の機能をテストしていきます。
コード内に解説も記載していくので併せて読んでみてください。
page.test.tsx
import Page from './page';
+ import { render, screen, waitFor } from '@testing-library/react';
+ import mockRouter from 'next-router-mock';
+ import userEvent from '@testing-library/user-event';
+ import { ReactNode } from 'react';
// テスト環境でのルーティング機能を生成するためにモックを作成する
+ jest.mock('next/router', () => require('next-router-mock'));
// Linkのモックを生成するための型定義
+ jest.mock('next/link', () => {
+ interface MockLinkProps {
+ children: ReactNode;
+ href: string;
+ }
// Linkに入っている要素を取得する。
// mockRouter.push(href)によって現在のパスがhrefに変更されてルーティングがシュミレートされる
+ const MockLink = ({ children, href }: MockLinkProps) => {
+ return <a href={href} onClick={() => mockRouter.push(href)}>{children}</a>;
+ };
+ MockLink.displayName = 'Link';
// MockLinkがレンダリングされると`onClick`イベントハンドラが設定された<a>要素が表示される
+ return MockLink;
+ });
describe('Page', () => {
test ('should render without crashing', () => {
render(<Page />);
});
+ test('navigates to /sample when get started button is clicked', async () => {
+ render(<Page />);
+ mockRouter.setCurrentUrl('/');
+ const getStartedButton = screen.getByRole('button', { name: /Button/i });
+ userEvent.click(getStartedButton);
+ await waitFor(() => expect(mockRouter.asPath).toEqual('/sample'));
+ });
})
おわりに
Jestを使ったnext/link
のテストを作成する方法を解説していきました。
もし間違っているところや、もっといいやり方があったらコメント等で教えてもらえると嬉しいです。
最後まで読んでくださりありがとうございました!
Discussion