---
title: "テスト用 Mock API: Prism、WireMock、MSW、json-server"
description: "サンプルのアドレスではなくローカルの Mock API で開発・テストする方法。OpenAPI から Prism、WireMock、MSW、json-server を例付きで。"
url: https://example-petstore.com/ja/guides/mock-api
language: ja
---

# サンプルのアドレスではなく Mock API でテストする

api.example-petstore.com のような架空のアドレスを指すコードも、実際のリクエストを送信します。そのリクエストは、その名前を所有している誰かに届きます。Mock API なら、同じ手軽さをそのリスクなしで得られます。自分のマシン上やテストの中で動作し、すぐに応答し、常に期待どおりのデータを返します。

## サンプルのアドレスを使わない理由

- 実在のドメインのように見えるサンプルのアドレスは、他人が登録している可能性があります。その場合、キーやトークンを含むヘッダーも含めて、すべてのリクエストがその人のサーバーに届きます。
- `api.example.com` のように example.com の下で使われていない名前はまったく名前解決されないため、コードは実際の応答をどう処理するかを示す前に、タイムアウトや DNS エラーで失敗します。
- 公開サーバーに依存するテストは遅く不安定で、そのサーバーが変わると動かなくなります。

Mock API はこの 3 つをすべて解決します。`localhost` またはテストプロセスの中で待ち受けるので、何もマシンの外に出ません。

## どのツールをいつ使うか

| ツール | 向いている用途 | 動作形態 |
| --- | --- | --- |
| Prism | OpenAPI の定義があり、それに従った応答がほしい場合 | ローカルサーバー（Node.js または Docker）、ポート 4010 |
| WireMock | 正確に記録した応答、エラーケース、遅延。言語を問いません | ローカルサーバー（Java または Docker）、ポート 8080 |
| MSW | JavaScript と TypeScript: フロントエンド開発と単体テスト | ブラウザー内、または Node.js のテストプロセス内 |
| json-server | 1 つの JSON ファイルから動く REST API。プロトタイプ向け | ローカルサーバー（Node.js）、ポート 3000 |

Swagger Petstore サンプル API そのものを使う場合は、公式イメージをローカルで実行してください。詳しくは [Swagger Petstore をお探しですか？](https://example-petstore.com/ja/guides/swagger-petstore)をご覧ください。

## Prism: OpenAPI ファイルから

Prism は OpenAPI（または Swagger 2.0）の定義を読み込み、そこにあるすべてのオペレーションに、そのファイルの例やスキーマで応答します。定義に合わないリクエストには分かりやすい検証エラーが返るため、本物の API ができる前にクライアントを確認するのに役立ちます。

```
# Node.js の場合
npm install -g @stoplight/prism-cli
prism mock openapi.yaml

# Docker の場合
docker run --init --rm -v "$(pwd)":/tmp -p 4010:4010 stoplight/prism:5 mock -h 0.0.0.0 /tmp/openapi.yaml

# その後
curl http://127.0.0.1:4010/pets
curl http://127.0.0.1:4010/pets/1 -H "Prefer: code=404"
```

`Prefer` ヘッダーを使うと、エラーコードや名前付きの例など、定義の中から特定の応答を選べます。`--dynamic`（`-d`）を付けると、Prism はリクエストのたびにスキーマから新しいデータを生成します。

## WireMock: 記録された応答

WireMock は、自分で書いたり記録したりしたスタブファイルから応答します。どの言語でも使え、本物のサービスでは狙って起こすことが難しい遅い応答や障害も再現できます。

```
# mocks/mappings/pet.json
{
  "request":  { "method": "GET", "url": "/v1/pets/1" },
  "response": {
    "status": 200,
    "headers": { "Content-Type": "application/json" },
    "jsonBody": { "id": 1, "name": "Rex", "status": "available" }
  }
}

# mappings/ を含むフォルダー（大きなボディ用の __files/ も）を指定して起動
docker run -it --rm -p 8080:8080 -v "$(pwd)/mocks":/home/wiremock wiremock/wiremock

curl http://localhost:8080/v1/pets/1
```

タイムアウトをテストするには応答に `"fixedDelayMilliseconds": 3000` を、再試行をテストするには `503` などのステータスを追加します。`/__admin` の管理 API を使うと、テストからスタブを追加したり、どのリクエストが届いたかを確認したりできます。

## MSW と PHP のモック: テストの中で

Mock Service Worker は、アプリケーション自体の中でリクエストを横取りします。ブラウザーでは Service Worker を通じて、Node.js ではテストプロセスの中で動作します。テスト対象のコードは通常のベース URL を呼び出し続け、追加のサーバーは動きません。

```
// handlers.js
import { http, HttpResponse } from 'msw'

export const handlers = [
  http.get('https://api.example.com/v1/pets/:id', ({ params }) =>
    HttpResponse.json({ id: Number(params.id), name: 'Rex', status: 'available' })),
  http.post('https://api.example.com/v1/pets', () =>
    HttpResponse.json({ error: 'name is required' }, { status: 400 })),
]

// テストの中で（Node.js）
import { setupServer } from 'msw/node'
const server = setupServer(...handlers)
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
```

`onUnhandledRequest: 'error'` を指定すると、コードがハンドラーのないアドレスを呼び出した時点でテストが失敗します。そのため、置き忘れたサンプルのアドレスが本番環境ではなくテスト実行の段階で見つかります。ブラウザーでは、`npx msw init public/` を一度実行し、`msw/browser` からワーカーを起動します。

PHP のテストでは、Guzzle の `MockHandler` がテストプロセスの中で同じ役割を果たします。Symfony には `MockHttpClient` があります。

```
// PHP, Guzzle: ネットワークを使わず、順番に応答
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;

$mock = new MockHandler([
    new Response(200, ['Content-Type' => 'application/json'], '{"id": 1, "name": "Rex", "status": "available"}'),
    new Response(400, [], '{"error": "name is required"}'),
]);
$client = new Client(['handler' => HandlerStack::create($mock), 'base_uri' => 'https://api.example.com/v1/']);

// PHP, Symfony
$client = new Symfony\Component\HttpClient\MockHttpClient(
    [new Symfony\Component\HttpClient\Response\MockResponse('{"id": 1, "name": "Rex"}')],
    'https://api.example.com/v1/'
);
```

ハンドラー内のアドレスは `api.example.com` です。これは予約済みの名前なので、リクエストがモックをすり抜けても本物のサーバーには決して届きません。

## json-server: 手早く REST API を

json-server は、1 つの JSON ファイルを、一覧・詳細・作成・更新・削除のルートを備えた REST API に変えます。変更はファイルに書き戻されるので、プロトタイプやデモに便利です。

```
# db.json
{
  "pets":   [ { "id": "1", "name": "Rex", "status": "available" } ],
  "orders": []
}

npx json-server db.json

curl http://localhost:3000/pets
curl -X POST http://localhost:3000/orders -H "Content-Type: application/json" -d '{"petId": "1"}'
```

検証や認証の機能はないため、プロトタイプにとどめてください。契約テストには Prism や WireMock のほうが適しています。

## 本物の API への切り替え

ベース URL は設定に置き、開発とテストではモックを値にして、本物のアドレスはアプリケーションが実際に動く場所だけで使います。

```
# .env.development
API_BASE_URL=http://localhost:4010

# .env.test
API_BASE_URL=http://localhost:8080

# 本番: ホスティング環境で設定し、リポジトリには決して入れない
API_BASE_URL=https://api.your-real-service.com
```

サンプルのアドレスが本番環境に届くのを防ぐチェックも含めた詳しい説明は、[API クライアントと SDK の設定](https://example-petstore.com/ja/guides/api-base-url)をご覧ください。

## 関連ガイド

### [API クライアントと SDK の設定](https://example-petstore.com/ja/guides/api-base-url)

ベース URL をコードから切り離して実際のサービスを指すようにし、サンプルのアドレスが本番環境に届かないようチェックを追加します。

### [Swagger Petstore をお探しですか？](https://example-petstore.com/ja/guides/swagger-petstore)

Swagger Petstore サンプル API の本当のベース URL、動作するリクエスト例、テスト用キー、Docker で自分のコピーを動かす方法。

### [安全に使えるサンプル値](https://example-petstore.com/ja/guides/example-values)

予約済みのドメイン、IP 範囲、AS 番号、MAC アドレス、電話番号、テスト用カード。コピーされても無害な例のために。

## 出典

- [Prism](https://github.com/stoplightio/prism) Stoplight
- [WireMock Docker images](https://github.com/wiremock/wiremock-docker) WireMock
- [Mock Service Worker](https://mswjs.io/docs/) MSW
- [json-server](https://github.com/typicode/json-server) GitHub
