Next.jsでtsxがテストできるところまでvitestの環境構築方法

に公開

はじめに

  • Next.jsプロジェクトでvitestを使ってコンポーネントテストを行う環境構築について解説します。
  • コンポーネントテストを実装するまでの環境構築をAIにやらせると、変な設定を繰り返し、いつまでも終わらないので、一度しっかりとプロンプトを作成しておこうと思いました。

必要なパッケージのインストール

npm install -D vitest # 開発環境にのみインストール
npm install --save-dev @testing-library/react # Reactコンポーネントをレンダリングするためのライブラリ(render, screen, fireEventを提供)
npm install --save-dev @testing-library/jest-dom # テストのアサーションの拡張ライブラリ
npm install --save-dev jsdom # 仮想的なブラウザ環境をNode.js上で再現(Jestには内包されているが、vitestでは別途インストール必須)
npm install --save-dev @vitejs/plugin-react

vitest-setup.ts の作成

プロジェクトルートに vitest-setup.ts を作成します:

import "@testing-library/jest-dom/vitest";

このファイルの役割:

  • @testing-library/jest-dom はJest向けに作られているため、Vitest用に変換が必要
  • Vitest用に jest-dom のマッチャーを正しくexpectに追加登録
  • 以下のような書き方が可能になります:expect(screen.getByRole('button')).toBeInTheDocument();

vite.config.ts の設定

/// <reference types="vitest" />
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    setupFiles: ["./vitest-setup.ts"],
  },
});

設定内容の説明:

  • /// <reference types="vitest" />: このファイル内でvitestの型情報を扱えるようにする。これがないと、testをキーにした設定が書けない
  • setupFiles: テスト実行前に読み込むファイルを指定

テストファイルの作成例

// @vitest-environment jsdom 
// ↑ファイルの一番上に記述(必須)

import App from "../src/app/App";
import * as matchers from "@testing-library/jest-dom/matchers";
import { expect, describe, it } from "vitest";
import { render, screen } from "@testing-library/react";

expect.extend(matchers);

describe("App", () => {
  it("should render", () => {
    render(<App />);
    expect(screen.getByText("App")).toBeInTheDocument();
  });
});

各行の解説:

  • // @vitest-environment jsdom: このファイルをjsdom環境で実行(documentやwindowが使用可能に)
  • import * as matchers: 便利なマッチャーを全てインポート
  • expect.extend(matchers): 標準のマッチャーを拡張

よく使う実用的なテクニック

エンドポイントのモック

MSW(Mock Service Worker)を使用することで、APIエンドポイントを効率的にモックできます:

import { setupServer } from "msw/node";
import { http, HttpResponse } from "msw";

const server = setupServer(
  http.get("*", ({ request }) => {
    const url = new URL(request.url);
    console.log(`【デバッグ】MSWがリクエストを受信: ${url.toString()}`);

    // service01へのリクエストを処理
    if (url.toString() === "http://localhost:3000/api/mail") {
      return HttpResponse.json({name : "fatricepaddy"});
    }

    if (url.toString() === "http://localhost:3000/api/reply") {
      return HttpResponse.json({data : "hello"});
    }

    console.log("【デバッグ】MSWが404を返します");
    return new HttpResponse(null, { status: 404 });
  }),
);

トラブルシューティング

test.ts → test.tsx への変更が必要

FindServices.test.ts というファイル名で以下のようなJSXを含むコードを書くと失敗します:

render(<FindServices />);

原因: .ts ファイルではJSXがパースできないため

解決方法: ファイル拡張子を .tsx に変更する

エラー例

実装例

今回の内容を実装したサンプルプロジェクトをGitHubで公開しています:

https://github.com/FatRicePaddyyyy/vitest-setup

参考資料

https://qiita.com/hiroXXI/items/2e31eab406f363a8c470
https://zenn.dev/apple_yagi/articles/b2b96af1fd355c
https://qiita.com/Qiitakumin/items/914602de042e029ba7f4

Discussion