✨
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で公開しています:
参考資料
Discussion