テストコードの書き方は以下に従ってください 【出力要件】 - 提供されたアウトラインの `describe` ブロックの構造とテストケース名(ドキュメントとしての意図)をそのまま維持してください。 - すべての `it.todo` を実行可能な `it` に変更し、テストコードを実装してください。 - テストコードを実装し終えたら `npm run test テストファイル` でテストを実行し、テストが失敗したら以下の観点で判断してください - テストコードが間違っている:テストコードを修正してください - 実装やテスト内容が間違っている:該当テストはスキップしてユーザに確認をしてください 【テスト実装における絶対のルール】 1. テストデータのライフサイクル管理(必須事項) - テストデータの作成(Insertなど)は、その前提条件(コンテキスト)を共有する関連した `describe` ブロックの中の `beforeEach` で行ってください。 - テストデータの削除(クリーンアップ)は、データを作成したのと同じ `beforeEach` の中で、Vitestの `onTestFinished` フックを利用して実行してください。 - 実装イメージ: `beforeEach(async () => { /* データ作成 */ onTestFinished(async () => { /* データ削除 */ }); });` - これにより、セットアップとティアダウンを高い凝集度で保ち、テストの成否に関わらず確実に状態がリセットされる完全な独立性(Test Isolation)を保証してください。 2. AAA(Arrange-Act-Assert)パターンの徹底 テストコード内は空行などで視覚的に3つのフェーズに分け、それぞれの役割を混同させないでください。 - Arrange(準備): APIモックの定義や、各 `it` 固有の追加の前提条件を構築します。Arrangeはitの中には記載しないでください。 - Act(実行): テスト対象の振る舞いを1つだけ実行します。itの中で実行します。 - Assert(検証): 「事後条件」と「不変条件」を検証します。itの中で実行します。 3. モックの排除とインフラの扱い - 対象コードの内部モジュール(RepositoryやAPI Clientなど)に対して `vi.mock` や `vi.spyOn` を使用することは「絶対に」禁止します。 - データベース(状態ベーステスト): 実際のデータベースを使用します。ORM等を用いて検証してください。 - 外部HTTP通信: 内部のHTTPクライアントをモックするのではなくDockerで起動しているprismサーバを利用してください。 4. 契約による設計(Design by Contract)の具現化 - 事後条件の検証: Actフェーズで得られた「戻り値(出力値)」と、データベースの「更新後の状態(SELECTして確認)」の両方をアサートしてください。 - 不変条件の検証: 異常系(エラー発生時)のテストにおいては、エラーがスローされることの検証に加えて、「データベースの状態がAct実行前と変わっていないこと(中途半端に更新・削除されていないこと)」を必ずアサートに含めてください。 5. 可読性と保守性 - `beforeEach` にデータ準備をまとめる場合でも、各 `it` ブロック内を読んだだけで「何がテストされているか」「なぜそのアサートになるのか」が推測できるように、テストの意図を明確に保ってください。 6. テストユーティリティを活用する - `src/test-utils/` に存在するテストユーティリティ関数を活用してください - また、必要なユーティリティ関数があれば追加・改修してください - テストコードが増えるに連れ、よりよいユーティリティ関数が整備可能ならゼロベースで再構築してください