APIモックサーバーのWireMockを動かしてみる。


# 概要

[システムアイ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/systemi23)の9日目の記事になります。  
この概要を書いているときに、去年も同じ9日目に記事を書いていたことに気づきました。  
去年のアドベントカレンダー以降、何も書いていなかった自分に反省しつつ、今回も現場で使用していたツールWireMockの紹介をしようと思います。

# WireMockって何？

[WireMock](https://wiremock.org/)はHttpベースのサービスやAPIのテストやシミュレーションを行うためのツールです。
ユニットテストのモックフレームワークや、CI実行時のスタブサーバーとしても利用できます。

java、nodejsなどにも言語の対応しており、dockerで別プロセスとして起動し、実行することもできます。

## 特徴

WireMockは他のAPIモックツールと比べて、以下のような特徴があります。

* スタブファイルの分離
JSONファイルとしてリクエストとそれに対するレスポンスのスタブを、ソースコードと分離できる。
　　
* リクエストのマッチング
リクエスト情報を正規表現で記載できる。
　　
* レスポンスの定義
レスポンスの内容を細かく設定できて、ステータスコード、ボディ、ヘッダーの設定できる。
　　
* リクエストの状態管理
テスト時にそのリクエストが何回行われたのかを計測したり、リクエストの値に応じて、レスポンスの値を変えることができる。
　　
* 記録と再生
実際のサービスのリクエスト、レスポンスの内容を記録できるので、
仕様書がなくてよく分からなくても、実際の処理を流すことでスタブを作成することができる。

# 動かしてみる

このツール自体、Javaやnodejsのパッケージとしてインストールすることも可能なのですが、今回はdockerを利用したもので検証します。
実際の現場では、Windows（WSL）経由で導入したので、今回はMacで動かしてみます。

## 環境

Mac Ventura

サンプルファイルをGitHubリポジトリに挙げているので、良かったら動かしてみてください。  
[wiremock_sample](https://github.com/hidetofukuda/wiremock_sample/tree/master)

`docker compose`の実行が上手くいくと、Wiremockの画面が出てきます。
![wiremock画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317288/838d8d4d-7138-a2b4-4272-34b03955762a.png)

## ファイル構成

```text
docker
└ wiremock    　
　　　├─__files
　　　└─mappings
```

WireMockを使用するにあたり、利用するフォルダーが2つあります。

* `mappings`  
スタブのJSONを格納します。docker起動時にこのフォルダーを
ファイル昇順で読み込み、同じリクエストのスタブファイルが読み込まれた場合は、上書きされます。

* `__files`
スタブでやり取りするファイル情報をここに格納できます。  
アンダーバーが2つあることに注意するしてください。  
`application/zip`ヘッダーで、ダウンロードするようなファイルも置き換えることができます。

## スタブファイル

`mappings`ファイルに入るスタブの構成は以下の通りになります。そのままになってしまいますが`request`キーに期待されるリクエストのメソッドやURL、`response`に返却値を設定します。

```Json
{
  "request": {
    "method": "GET",
    "url": "/test/sample"
  },

  "response": {
    "status": 200,
    "body": "Hello, world!",
    "headers": {
        "Content-Type": "text/plain"
    }
  }
}
```

## ファイルダウンロードAPIのスタブ

JSONに書いてあるファイルを外部ファイルとして指定することもできます。
JSONで指定されている`sample.zip`は`__file`フォルダーに格納しておきます。

```Json
{
    "request": {
      "method": "GET",
      "url": "/test/csv",
    },
    "response": {
      "status": 200,
      "bodyFileName": "sample.zip",
      "headers": {
          "Content-Type": "application/zip"
      }
    }
  }
```

## docker composeの中身

`mapping`と`__files`をdockerへマウントします。

```yaml
version: "3"
services:
  wiremock:
    image: "wiremock/wiremock:latest"
    container_name: my_wiremock
    volumes:
      - ./wiremock/_files:/home/wiremock/_files
      - ./wiremock/mappings:/home/wiremock/mappings
    ports:
      - 8443:8080
```

## 動作確認

別ターミナルを開いてcurlを実行すると、`response`で指定したメッセージが返却されます。

```bash
$ curl http://localhost:8443/test/sample
Hello, world!
```

fileダウンロードもcurlオプションで出力することで、ファイルを取得できます。

```bash
$ curl http://localhost:8443/test/csv -o sample.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  6916    0  6916    0     0   472k      0 --:--:-- --:--:-- --:--:--  750k
```

# 最後に

今回は事前準備を極力少なくできるように、curlコマンドで確認するサンプル紹介になってしまいましたが、
JavaやnodejsでのユニットテストやCIのシナリオテストにも使うことができるので、興味を持ってもらえたらぜひ使ってみてください。

# 参考にしたサイト

[公式ドキュメント](https://wiremock.org/)