【完全版】jestテストコードの書き方ガイド|Next.js対応・ユニットテスト基礎から実践まで解説
- Web開発
- アプリ開発
初めに
Jestとは?特徴と導入メリット
Jestが選ばれる理由
JestはMeta(旧Facebook)が開発したJavaScriptテストフレームワークです。既存のテスト環境とは異なり、テストランナー・アサーション・モック機能・スナップショットテストが1つに統合された“オールインワン型” が最大の特徴です。複数ライブラリを組み合わせる場合に比べ、初期セットアップで迷うポイントが少なく、短時間でテスト環境を立ち上げられます。
さらに以下の点でも多くの現場で支持されています。
■ 実行速度の速さ
Jestは内部的にテストをインテリジェントにキャッシュし、変更があった部分だけを差分実行します。大規模なモノレポや企業システムでも“体感できる速さ”で動作するため、CIでのテスト時間を最小限にできます。
■ 直感的なAPI
describe / test / expect というシンプルな記法でテストが書け、これから学ぶ人でも理解しやすい記法です。テスト失敗時のエラーメッセージもわかりやすい形式で表示されるため、デバッグ負担も減らせます。
■ React / Next.js との高い親和性
React Testing Library(RTL)との組み合わせは広く利用されており、多くのNext.jsプロジェクトで採用されています。ただし、公式ドキュメントやサンプルではVitestなど他のテストランナーも紹介されており、必ずしもJestだけが前提というわけではありません。
Next.js特有の以下のようなポイントも、Jestとモックを組み合わせることで多くのケースに対応できます。
- ルーティング(next/router)モック
- Imageコンポーネントのモック
- getServerSideProps のテスト
- Edge Runtime向けのロジックをモックして振る舞いを検証(※実際のEdge Runtime環境を完全再現するわけではありません)
■ コミュニティ・情報量の圧倒的多さ
GitHubリポジトリ、StackOverflow、Qiita、Zennなどに多数の実例記事があり、困ったときの検索性が高い点もビジネス開発に向いています。企業向けの大規模フロントエンドでも安心して使える理由がここにあります。
テストコードを書く価値
テストコードは単なる“品質向上のための追加作業”ではありません。実務では以下のような価値があります。
1. リファクタリングの安全性向上
リファクタリングを恐れず実施できることで、技術的負債の蓄積を防ぎます。事業開発や長期運用プロダクトにおいて最大のメリットです。
2. ドキュメントとしての役割
テストは「この機能はこう動くべき」という仕様を自然言語ではなく“コード”として残すため、後任エンジニアの理解が早まり、開発スピードが向上します。
3. バグの再発防止
バグの再発防止は実務において最も重要です。
一度発生したバグを、その再現条件ごとテストにして保存することで、次回以降のリリースで同じバグが出ることを確実に防げます。
4. 自動化による品質ゲートの構築
GitHub Actions、GitLab CI、CircleCI などと連携することで、PR(Pull Request)作成時に自動的にテストが走る“品質ゲート”を作れます。
人間が目視チェックする前に機械的に品質を担保できるため、開発プロセス全体が強固になります。
どのような場面で役立つのか
Jestは以下のような場面で特に効果を発揮します。
- 入力フォームのバリデーションルール確認
- API通信の成功/失敗パターンのテスト
- 複雑な条件分岐を含んだビジネスロジックの検証
- UIコンポーネントのレンダリング条件テスト
- 依存関数のモックによる副作用切り離し
Next.js固有の場面ではさらに活躍します。
- getServerSideProps が適切な props を返すか
- getStaticProps 内部のビジネスロジックが期待どおりのデータを返すか(※ビルド時エラーそのものは統合テストや実ビルドで検知するのが現実的)
- API Routes が特定のHTTPステータスを返すか
- next/router を使った条件分岐のテスト
Jestテストコードの基本構造
describe / test / expect の役割
Jestで最初に覚えるべき3つの関数は以下の通りです。
コードを“自然な文章のように読みやすい構造にする”ことが Jest の大きな利点です。
Matcherの使い方とよく使う記法
Jestには幅広いMatcherが用意されており、実務では以下がよく使われます。
- toBe():プリミティブな値の判定
- toEqual():オブジェクトや配列の深い比較
- toContain():部分一致の確認
- toThrow():例外発生の確認
- toHaveBeenCalled():関数呼び出しの監視
React Testing Libraryと組み合わせると、
- toBeInTheDocument()
- toHaveTextContent()
- toHaveAttribute()
といった“DOM寄りのマッチャー”も利用でき、よりユーザーに近い視点でテストが書けます。
モック(mock)の基礎
Jest.mock()を使うことで外部依存を切り離し、テストを安定させることができます。
たとえば、fetchをモックすれば、ネットワーク障害やAPI遅延に影響されないテストを実現できます。
global.fetch = jest.fn().mockResolvedValue({
json: () => Promise.resolve({ message: “Hello” }),
});
関数を部分的に監視したい場合は jest.spyOn() が便利です。
Jestの環境構築と設定方法(Next.js対応)
Next.jsでJestを使うための設定手順
Next.jsプロジェクトでは、以下のようにセットアップします。ここでは pages router を前提とした一例を紹介します(App Router の場合は一部設定やモック対象のモジュールが異なります)。
1. パッケージのインストール
npm install –save-dev jest @testing-library/react @testing-library/jest-dom @testing-library/user-event
2. jest.config.js の作成
Next.js特有の alias(@/) やCSS Modulesを扱うための設定が必要です。
3. CSS・画像のモック設定
module.exports = {
moduleNameMapper: {
“\.(css|less|scss)$”: “identity-obj-proxy”,
“^@/(.*)$”: “<rootDir>/$1”,
},
testEnvironment: “jsdom”,
};
4. setupTests.ts の作成
import “@testing-library/jest-dom/extend-expect”;
Babel・TypeScript設定の注意点
最新のJestはESModulesもサポートしていますが、設定がやや複雑になるため、実務では以下のいずれかを組み合わせて運用するケースが一般的です。
- Babel → パフォーマンス優先
- ts-jest → 型整合性優先
よくあるエラーと対処法
実務でよく遭遇する問題と解決策を整理します。
■ Next/Image がエラーを起こす
jest.mock(“next/image”, () => ({
__esModule: true,
default: (props) => <img {…props} />,
}));
■next/router をモックしたい(pages router を利用している場合)
jest.mock(“next/router”, () => ({
useRouter: () => ({
push: jest.fn(),
pathname: “/”,
}),
}));
※App Router(app/ ディレクトリ)を利用している場合は next/navigation をモックする必要があります。
■ getServerSideProps のテストで失敗
- fetchをモックする
- context引数を適切にモックする
- Cookies や query の再現にも注意
ユニットテストの書き方と実例集
関数のテストコード例
describe(“calcTax”, () => {
test(“10%税の計算”, () => {
expect(calcTax(1000)).toBe(1100);
});
test(“0以下の値のとき例外を返す”, () => {
expect(() => calcTax(-1)).toThrow();
});
});
境界値を含むテストパターンを網羅すると、より堅牢になります。
API処理のテスト(Next.js API Routes)
import handler from “@/pages/api/hello”;
test(“正常にメッセージを返す”, async () => {
const req = {};
const res = {
status: jest.fn().mockReturnThis(),
json: jest.fn(),
};
await handler(req, res);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toHaveBeenCalledWith({ message: “Hello” });
});
コンポーネントテスト(React Testing Library)
import { render, screen, fireEvent } from “@testing-library/react”;
import Counter from “./Counter”;
test(“クリックでカウントが増える”, () => {
render(<Counter />);
fireEvent.click(screen.getByRole(“button”));
expect(screen.getByText(“1”)).toBeInTheDocument();
});
実務で使えるJestのベストプラクティス
テスト設計の考え方
実務では「すべてテストする」のではなく、
リスクの大きい部分からテストを書く
ことが重要です。
保守性と再利用性を高める書き方
- 共通mockを test/mocks 配下に切り出す
- fixture データを使いまわす
- beforeEach で毎回同じ初期化を行う
- テスト名に“期待する結果”を書く
チーム開発での注意点
- カバレッジ目標を明確化
- test/spec ファイルの命名ルール統一
- PR作成時のテスト実行を必須化
- 複雑なコンポーネントは“責務を減らすリファクタ”を先行
テストはチーム全体の資産であり、属人化を避ける仕組みづくりが非常に重要です。
まとめ
Jestは現代フロントエンド開発において不可欠なテスト基盤です。Next.jsのような複合的なフレームワークにおいても、環境構築から実践的ユニットテスト、コンポーネントテスト、APIテストまで幅広くカバーできます。
テストは一度書き始めると、リファクタリングの安心感やバグ再発防止など多くのメリットをもたらし、長期的に大きな価値を生みます。
「【完全版】jestテストコードの書き方ガイド|Next.js対応・ユニットテスト基礎から実践まで解説」
の詳細が気になる方は、
お気軽にお問い合わせください
Y's Blog 編集部

