テスト用APIモック作成の実践ガイド

INEZA Felin-Michel

INEZA Felin-Michel

22 5月 2026

テスト用APIモック作成の実践ガイド

Apidog エンタープライズ

オンプレミスデプロイ

SSO & RBAC

SOC 2 準拠

Apidog Enterpriseを見る

ライブAPIに依存するテストは、間違った理由で失敗するテストです。ステージングサーバーがダウンしたり、サードパーティのレート制限がかかったり、チームメイトがレコードを変更したりすると、コードは問題ないのに突然スイートが赤くなることがあります。APIをモック化することで、その脆弱性が取り除かれます。実際のエンドポイントを、要求されたとおりのレスポンスを毎回返す、制御された代替物に置き換えるのです。

このガイドでは、テストのためにAPIをモック化する実際の手順を説明します。スキーマを定義し、モックレスポンスを生成し、テストコードをモックに向け、実際のサーバーではめったに発生しないエラーパスをカバーします。例では小規模な注文管理APIを使用していますが、このワークフローはあらゆるRESTまたはGraphQLサービスに適用できます。

APIモック化が正しい選択である場合

テストしたいものがネットワークではなく、あなた自身のコードである場合にAPIをモック化します。単体テストやほとんどの結合テストはこのカテゴリに分類されます。クライアントが200を正しく解析し、503でリトライし、404で明確なメッセージを表示することを確認したいのです。これらに実際のサーバーは必要ありません。

契約テストと薄い層のエンドツーエンドチェックのために、実際のAPIを残しておきます。これらは、モックがまだ現実に一致していることを確認するために存在します。すべてをモック化し、ライブサービスに対して検証しない場合、本番環境が破損している間もスイートはグリーン表示のままです。大まかな分け方は、速度と分離のためにモック化し、契約を確認するために実際のものをヒットさせるというものです。それぞれがどこに適合するかをより深く理解するには、APIモック化が役立つシナリオモックサーバーと実際のサーバーの違いに関するこの解説を参照してください。

5つのステップからなるワークフローの概要

テストのためにAPIをモック化する手順は、言語やフレームワークに関係なく、常に次の5つのステップです。

  1. スキーマを定義することで、モックが実際のレスポンスの形を反映するようにします。
  2. そのスキーマから、静的または動的なモックレスポンスを生成する
  3. そのレスポンスをURLで提供するモックサーバーを実行する
  4. ベースURLを設定可能にすることで、テストをモックに向ける
  5. 実際のサーバーが要求に応じて生成しないエラーパスをテストする

このガイドの残りの部分では、具体的な例として、GET /orders/{id}エンドポイントを持つ小規模な注文管理APIを用いて各ステップを説明します。このエンドポイントを常に念頭に置いてください。

ステップ1:スキーマを定義する

モックは、実際のレスポンスの形を反映している場合にのみ役立ちます。スキーマから始めましょう。APIにすでにOpenAPIドキュメントがある場合は、それを使用します。ない場合は、テスト対象のエンドポイント用に記述します。以下は、GET /orders/{id}の簡略化された定義です。

paths:
  /orders/{id}:
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  id: { type: string }
                  status: { type: string, enum: [pending, shipped, delivered] }
                  total: { type: number }
                  items: { type: array, items: { type: object } }
        '404':
          description: Order not found

スキーマには2つの役割があります。モックにどのフィールドを返すかを指示し、単一の信頼できる情報源を提供します。バックエンドが契約を変更した場合、スキーマを更新すれば、そこから派生したすべてのモックは正確な状態を保ちます。スキーマファーストのモック化は、API契約テストの信頼性を維持するものです。

ステップ2:モックレスポンスを生成する

レスポンスボディを作成する方法は2つあります。

静的レスポンスは固定されたJSONです。正確なペイロードを一度記述すると、モックはそれを変更せずに返します。これらは予測可能でアサートしやすいため、既知の単一値が必要な単体テストに最適です。

動的レスポンスはリクエストごとに生成されます。"total": 149.99をハードコーディングする代わりに、モックはフィールドをリアルな生成値で埋めます。idにはUUID、statusにはランダムな列挙型メンバー、totalには妥当な通貨金額などです。動的データは、長い文字列で壊れるパーサーや予期せぬnullフィールドなど、単一の固定ペイロードが隠すバグを検出します。

ほとんどのチームが両方を使用しています。アサーションが多いテストには静的ペイロードを、ファズスタイルのカバレッジには動的生成を使用します。Apidogを使用すると、どちらも手動で記述する必要はありません。Apidogはスキーマを読み込み、emailphoneavatarなどのフィールド名を正しいデータ型にマッピングしてモックエンドポイントを自動生成します。ブラウザをモックURLに向けるだけで、すぐに有効なレスポンスが得られます。

ペイロードを手動で記述する場合は、現実的なものにしてください。"total": 0と空のitems配列を持つテスト注文は、素朴なパーサーを通過しますが、バグを隠します。本番環境に似た値を使用してください。つまり、リアルな合計金額、2つか3つの明細項目、実際に列挙型にあるステータスなどです。モックデータが実際の要求が返すものに近いほど、テストの価値は高まります。

ステップ3:モックサーバーを実行する

モックレスポンスは、それが提供されるまで何の役にも立ちません。ホスティングの選択肢は2つあります。

ローカルモックサーバーは、通常localhost:4010のようなポートで、あなたのマシン上で実行されます。高速でオフラインでも動作し、単体テストや結合テストのデフォルトです。Prismのような軽量ツールは、OpenAPIファイルから直接起動できます。

prism mock openapi.yaml
# Mock server listening on http://127.0.0.1:4010

クラウドモックサーバーはパブリックURLを持っています。モバイルアプリ、CIランナー、または外部協力者があなたのラップトップにアクセスせずにモックを呼び出す必要がある場合に利用します。Apidogはすべてのプロジェクトにホスト型クラウドモックURLを提供するため、別のネットワーク上のチームメイトもあなたと同じエンドポイントにアクセスできます。

テスト実行にはローカルを推奨します。ネットワーク遅延がなく、共有状態もないため、2つのビルドが衝突することはありません。デモやクロスデバイステストにはクラウドオプションを使用してください。

ステップ4:テストをモックに向ける

さて、テストコードを本番ではなくモックに接続します。最もクリーンなアプローチは、設定可能なベースURLを使用することです。環境変数から読み込むことで、同じテストファイルがローカルではモックに対して、契約ジョブでは実際のAPIに対して実行されるようにします。

// orderClient.test.js
import { getOrder } from './orderClient.js';

const BASE_URL = process.env.API_BASE_URL || 'http://127.0.0.1:4010';

test('parses a shipped order', async () => {
  const order = await getOrder('order_8842', BASE_URL);
  expect(order.status).toBe('shipped');
  expect(typeof order.total).toBe('number');
});

クライアントはベースURLを引数として受け取ります。本番コードでは、それがモック化されていることを知りません。CIでは、スイートが実行される前にAPI_BASE_URLをモックのアドレスに設定します。このパターンにより、モック化はアプリケーションロジックから完全に切り離され、本来あるべき場所に置かれます。パイプラインを通じてテストを実行する場合でも、CI/CDでAPIテストを自動化する際にも同じ考え方が適用されます。

ステップ5:エラーパスをテストする

これはほとんどのチームが見過ごしがちなステップですが、最も効果的なステップです。実際のサーバーは、要求してもめったに500を返しません。モックはコマンドでそれを返します。

シナリオ モックが返すもの あなたがアサートすること
レコードが見つからない 404 クライアントは明確な「見つかりません」エラーをスローする
サーバー障害 500 クライアントはリトライし、その後フォールバックを表示する
レート制限 Retry-Afterヘッダー付きの429 クライアントは適切な量だけ待機する
低速レスポンス 5秒の遅延後の200 クライアントはタイムアウトし、回復する
不正な形式のボディ 壊れたJSONの200 クライアントは正常に失敗し、クラッシュしない

Apidogの高度なモックルールを使用すると、リクエストに基づいて異なるレスポンスを返すことができます。たとえば、order_404のリクエストには404が返され、それ以外のIDには通常の200が返されます。これにより、ハッピーパスと障害の両方をカバーする1つのモックエンドポイントを持つことができます。これを強力なAPIアサーションと組み合わせることで、スイートはステータスコードだけでなく、動作も検証します。

増え続けるテストスイート全体でのモックの整理

単一のモックエンドポイントは簡単です。スイート全体に散らばった数百のエンドポイントは、チームが制御を失う原因となります。いくつかの習慣がセットを管理可能に保ちます。

モックは、それを使用するテストではなく、それが代替する実際のサービスによってグループ化します。決済APIが変更された場合、20個のテストファイルではなく、1箇所を更新したいはずです。モックフィクスチャには、order-shippedorder-rate-limitedのように、それが表すシナリオにちなんだ名前を付け、失敗したテストが明確に読めるようにします。モックはテストの一部であり、同じレビューを受ける価値があるので、テストの隣にバージョン管理でモック定義を保管します。

すべてのテストに独自のカスタムペイロードを与える衝動に抵抗してください。ほとんどのテストは、1つのフィールドが変更された同じ現実的な注文オブジェクトを必要とします。基本レスポンスを一度定義し、テスト対象のフィールドのみをオーバーライドします。これにより、スイートは読みやすく保たれ、契約変更が散らばったコピーではなく、1つの基本定義に影響するだけになります。API自動化のためのテストスイートを保守可能にするのと同じ規律が、その背後にあるモックにも直接適用されます。

モックの整合性を保つ

モックは乖離します。バックエンドがフィールドを追加したり、totalamountに名前変更したり、列挙型を変更したりすると、モックは古い形式を返し続けます。テストはパスしますが、本番環境は失敗します。これはモック化がうまくいかない最も一般的な方法であり、サイレントに発生します。スイートはモック自体を測定しているため、スイートの何も文句を言いません。

これを防ぐには2つの習慣があります。まず、バックエンドが公開するのと同じスキーマからモックを派生させることで、契約変更時に両方が一度に更新されます。OpenAPIファイルから生成されたモックは、そのファイルが変更されると再生成されますが、手動で入力されたモックはそうではありません。次に、定期的に実際のAPIに対して少数の契約テストを実行します。これらのテストの唯一の目的は、ライブレスポンスがモックが使用するスキーマにまだ一致していることを確認することです。それらが失敗した場合、ユーザーが気づく前にモックが古くなっていることがわかります。

コードレビュー中にモックをレビューすることも役立ちます。プルリクエストがAPIレスポンスを変更する場合、レビュアーは対応するモックも変更されているかを確認すべきです。モックを使い捨てのテストヘルパーとしてではなく、契約の一部として扱うことが、モック化されたスイートを何ヶ月もの変更にわたって信頼できる状態に保ちます。

スキーマを保持し、モックを生成し、それに対してテストを実行する単一の環境が必要な場合は、Apidogをダウンロードしてください。これにより、設計、モックサーバー、およびテストスイートが同期され、テスト対象のモックは常に現在の契約に準拠します。より広範なオプションについては、REST APIモックツールのまとめでフィールドを比較してください。

よくある質問

すべてのテストでAPIをモック化すべきですか?

いいえ。あなた自身のコードをチェックする単体テストや結合テストのためにモック化してください。モックがまだ本番環境に一致していることを確認するため、実際のAPIをヒットさせる少数の契約テストとエンドツーエンドテストを残しておきます。すべてをモック化すると、契約の乖離を隠してしまいます。

静的モックレスポンスと動的モックレスポンスの違いは何ですか?

静的レスポンスは、変更されない固定されたJSONペイロードであり、予測可能なアサーションに適しています。動的レスポンスは、リクエストごとに現実的な値で生成され、単一の固定ペイロードでは見逃される可能性のあるバグを検出します。ほとんどのチームが両方を使用しています。

モックの正確さをどのように維持しますか?

バックエンドが使用するのと同じスキーマ(理想的にはOpenAPIドキュメント)からモックを生成します。次に、実際のAPIに対して定期的に契約テストを実行し、ライブレスポンスがそのスキーマにまだ一致していることを確認します。それらが失敗した場合、モックの更新が必要です。

モックは低速なレスポンスや失敗するレスポンスをシミュレートできますか?

はい、できます。これがモック化する最も強力な理由の1つです。モックを構成して、500Retry-Afterヘッダー付きの429、または遅延した200を返すことができます。これにより、正常な実際のサーバーでは要求に応じて決して発生しない、リトライロジックやタイムアウトを検証できます。

テストにはローカルモックサーバーとクラウドモックサーバーのどちらを使用すべきですか?

テスト実行にはローカルモックサーバーを使用してください。高速で、ネットワーク遅延がなく、ビルド間の共有状態を回避できます。モバイルデバイス、CIランナー、または外部協力者があなたのマシンにアクセスせずにモックに到達する必要がある場合は、クラウドホスト型モックを使用してください。

ApidogでAPIデザイン中心のアプローチを取る

APIの開発と利用をよりシンプルなことにする方法を発見できる