🪩
メモ:Next.js Route Handlers のモックテストについて
Changelog
メモ
雑なメモ書き。
APIエンドポイントのモックテスト
Node.jsサーバ向け
DockerやSwagger、Prism等々でモックサーバを立ち上げる必要がある。
Next.js向け
モックサーバを立ち上げる必要がない。
React/フロントエンド向け
モックサーバを立ち上げる必要がない。
Storybookなど、フロントエンドを絡めたモックテストにとても有効。
ただし、モックハンドラーを用意したりの設定が必要。
Vitest公式ドキュメントで紹介されている方法がこれだったりする。
問題
- モックサーバを立ち上げる必要がある
- ライブラリ依存になる
- バージョンの相性を考慮しなければならない
- 単純なテストでは不要な、高機能すぎるが故の煩雑さ
実際に
next-test-api-route-handler
はnext@14.2.20
以降で動かない事例がある。(記事執筆時点)
解決
NextRequest
クラスかRequest
クラスで、リクエストのインスタンスを生成して各Route Handlersに渡す。
test/api/foo.test.ts
import { NextRequest } from "next/server";
import { describe, expect, it } from "vitest";
import { POST } from "@/app/api/route";
import type { Foo } from "@/models";
import { createAPIResponse } from "@/server";
describe("POST /api", () => {
const MOCK_URL = "http://localhost:3000/api";
it("正常なリクエストを処理できる", async () => {
const validBody: Foo = {
name: "foobar",
occupationalStatus: "STUDENT",
contactTool: "DISCORD",
contactDetail: "foobar#1234",
};
const request = new NextRequest(MOCK_URL, {
method: "POST",
body: JSON.stringify(validBody),
});
const response = await POST(request);
expect(response.status).toBe(200);
expect(await response.json()).toMatchObject(createAPIResponse(validBody));
});
it("不正なメールアドレスの場合エラーを返す", async () => {
const invalidBody: Foo = {
name: "foobar",
occupationalStatus: "STUDENT",
contactTool: "EMAIL",
contactDetail: "invalid-email",
};
const request = new NextRequest(MOCK_URL, {
method: "POST",
body: JSON.stringify(invalidBody),
});
const response = await POST(request);
expect(response.status).toBe(400);
const json = await response.json();
expect(json.error).toBeDefined();
});
});
createAPIResponse()
は別記事「TypeScriptやReactを書くときに意識していること」で紹介したハンドラーです。
レスポンスオブジェクトの生成をハンドラー化することで、テストも容易になります。
Discussion