【Next.js】API RoutesをJestでテストする際の「Response is not defined」エラー対処法

2024/03/23に公開

はじめに

少し詰まったので、解決までの内容をまとめます。

問題

以下のようなNext.jsのAPI Routesのコードに対して、Jestを使ってテストを実行すると、「Response is not defined」エラーが発生する。

app/api/users/route.ts
import { NextResponse } from "next/server";

export const GET = async () => {
    const users = await getUsers();
    return NextResponse.json(users, { status: 200 });
};

app/api/users/route.test.ts
import { GET } from "./route";

describe("GET /api/users", () => {
  it("ユーザー一覧情報を取得する", async () => {
    const res = await GET();
    const body = await res.json();
    expect(res.status).toBe(200);
    expect(body.length).toBe(1);
  });
});

エラーメッセージ

ReferenceError: Response is not defined

解決方法

テストファイルの先頭に以下のコメントを追記する。

/**
 * @jest-environment node
 */

このコメントにより、JestはテストをNode.js環境で実行するようになります。

この明示的な指示が必要な理由は、Reactコンポーネントのテストを行うために、
jest.config.tstestEnvironmentjsdomに設定していたからです。

jest.config.t
const config: Config = {
  // 省略
  testEnvironment: "jsdom",
};

これは、全てのテストファイルに対して、jsdom環境でテストを実行するように設定しています。
なので、APIのようなnode環境でテスト実行する必要がある場合は、明示的に指示してあげる必要があるということですね。

最終的なコード

api/users/route.test.ts
/**
 * @jest-environment node
 */
import { GET } from "./route";

describe("GET /api/users", () => {
  it("ユーザー一覧情報を取得する", async () => {
    const res = await GET();
    const body = await res.json();
    expect(res.status).toBe(200);
    expect(body.length).toBe(1);
  });
});

おわりに

エラーメッセージの内容を見た時に実行環境を疑うことすら出来なかったので、今回の経験を教訓にしたいと思います。

参考

Discussion