モック、スタブ、フェイク、エミュレーター: コーディング エージェントを使用した API 呼び出しのテスト

コードが API を呼び出すときは、実際の API が失敗するのを待たずにテストする方法が必要です。 あなたはから選択する5種類のスタンドインを持っています。 これらの名称は厳密に区別せずに使われるため、この記事での使い分けを以下に示します。

  • スタブ: HTTP クライアントまたは SDK 呼び出しのインプロセス置換で、あらかじめ用意された応答を返します。 高速で繰り返し可能であり、あなたが記述した応答のロジックをテストします。
  • モック: テストで呼び出しを確認できるように、コードが呼び出した方法も記録するスタブです。 スタブまで到達します。
  • 偽のサーバー: アプリが実際の API の代わりに HTTP 経由で呼び出す小規模な簡易サーバー (多くの場合、メモリ内)。 これは HTTP クライアントを実行しますが、アプリの向き先をその URL に設定する必要があります。
  • エミュレーター: 通常、サービスの所有者によって公開される、サポートする操作に関しては実際のサービスと同様に動作するサービスのローカル バージョン。 それをエラー処理に利用する前に、どのような制限や障害に対応しているかを確認してください。
  • インターセプティングプロキシ: アプリと API の間のネットワーク上に配置されます。 アプリは実際の URL にアクセスし、プロキシは要求を渡すか、定義した応答でそれらの一部に応答します。 アプリは通信をプロキシ経由で送信し、HTTPS の場合はプロキシの証明書を信頼する必要があります。

API を呼び出すコードをテストする方法

Approach テスト対象 必要なもの ちょうど~するとき
スタブまたはモック あなたの特定の応答に対するロジック あなたのテスト フレームワーク 単体テストでビジネス ロジック、解析、エラー 分岐をテストする
偽のサーバー HTTP クライアントとシリアル化 アプリ内のベースURL設定または設定スイッチ API がまだ存在しないか、または UI 作業用に安定したバックエンドが必要です
Emulator サポートされている操作の実際のサービスに近い動作 別のエンドポイントまたは接続文字列 サービスの所有者が 1 つ提供し、あなたはオフラインで開発する
テスト アカウントで使用する Real API 本物 資格情報、クォータ、料金 メインパスを最初から最後まで検証する
インターセプティング プロキシ SDK の再試行や応答ヘッダーを含む、実際の URL 上で実行中のアプリ プロキシ設定と証明書の信頼設定 アプリを変更せずに、エラー、制限、待機時間をテストできます

これらの 1 つ以上が必要です。 スタブは単体テストを高速に保ちます。 プロキシは、実際の API が不適切な動作をした場合のアプリ全体の動作を示します。 2 の組み合わせの詳細については、「Dev Proxy と単体テスト」を参照してください。

コーディング エージェントが構築するもの

アプリで API エラーを処理し、それが正しく動作することを示すようにコーディング エージェントに依頼すると、あなたの代わりにスタンドインが選択されます。 どれなのかを知るために、3 つのコーディング エージェント (210 回の実行) でテストを実行しました。 タスクでは、"レート制限を適切に処理して動作することを示す"、"実際の API 呼び出しにコストをかけずに検証する"、"OpenAI キーやインターネット接続なしでこれを実行する" などの言い回しが使用されました。

  • 作業コードを要求した 140 回の実行のうち 76% では、エージェントは失敗ケースを手作業で再現しました。fetch のスタブ、httpx.MockTransport、または使い捨ての HTTP サーバーを用いていました。
  • GitHub、OpenAI、または weather API を呼び出すアプリに対する105回の実行のうち61回で、エージェントはベース URL または構成スイッチをアプリに追加して、その模擬の接続先に到達できるようにしました。
  • 実際のAPIが使用可能で、プロンプトで除外されなかった75回の実行では、そのうち、実際のAPI URLでアプリをテストした実行は0件でした。

スタブは、単体テストに適した選択肢です。 そのギャップとは、彼らが省いている部分です。エージェントのスタブは、エージェントが想定しているエラーを返しますが、それが API から送られるエラーと一致するとは限りません。 そして、あなたのアプリで偽の船に到達するために追加されたスイッチ。

エージェントのテストを扱う方法

  • ロジック用のスタブを保持します。 高速で、エージェントが作成したブランチをテストします。
  • 実際のエラー形式を確認します。 プロバイダーの文書化された状態コード、ヘッダー、および本文フィールドに基づいて、各シミュレーションエラーを作成するようエージェントに依頼します。 ベア 429 では、アプリが retry-after を読み取ったり、課金エラーとレート制限を区別したりすることはテストされません。
  • テスト用に追加されたスイッチの確認 テストがフェイクにアクセスできるようにするためだけにエージェントがベース URL 設定を追加する場合は、その設定を本番コードに含めるかどうかを判断します。
  • 実際の URL で、障害をシミュレートした状態でアプリを 1 回実行します。 リリースする前に、実行中のアプリ、SDK、再試行ポリシーが API 独自のエラーで何を行うかを確認します。 エージェントのエラー処理を段階的に確認するには、「コーディング エージェントが記述したエラー処理を確認する方法」を参照してください。

アプリで試す

Dev Proxy は、開発用のインターセプト プロキシです。 アプリが既に呼び出している URL に対して定義した応答が返され、アプリのコードは変更されません。 構成で MockResponsePlugin を有効にします: devproxyrc.json

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/rc.schema.json",
  "plugins": [
    {
      "name": "MockResponsePlugin",
      "enabled": true,
      "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll",
      "configSection": "mocksPlugin"
    }
  ],
  "urlsToWatch": [
    "https://api.contoso.com/*"
  ],
  "mocksPlugin": {
    "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/mockresponseplugin.schema.json",
    "mocksFile": "mocks.json"
  }
}

次に、 mocks.jsonで応答を定義します。 これは、予測エンドポイントに対して503 ヘッダーを含むRetry-Afterが返されます。

{
  "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v3.3.1/mockresponseplugin.mocksfile.schema.json",
  "mocks": [
    {
      "request": {
        "url": "https://api.contoso.com/v1/forecast*",
        "method": "GET"
      },
      "response": {
        "statusCode": 503,
        "headers": [
          {
            "name": "Retry-After",
            "value": "10"
          }
        ],
        "body": {
          "error": "Service unavailable"
        }
      }
    }
  ]
}

開発プロキシを起動し、通常どおりにアプリを実行してください:

devproxy --config-file devproxyrc.json

モックと一致しない要求は、実際の API に送信されます。 まだ存在しないバックエンドが必要な場合、CrudApiPlugin はメモリ内データを使用して CRUD API をシミュレート します。 毎回ではなくランダムにリクエストの一部を失敗させる場合は、「ランダムなエラーでアプリをテスト」を参照してください。 開発プロキシをインストールするには、「 開発プロキシの設定」を参照してください。

次のステップ

参照