「サーバが出来ていない? 俺なら3分でモックを用意できるよ。」というために。

  • 231
    いいね
  • 0
    コメント

はじめに

フロントエンドを作っていたり他サーバと連携するバックエンドを作っていると、対向サーバが出来るまでダミーのモックサーバが欲しくなりますよね。
適当に固定のダミーデータを返すだけで良いのですが、本来の開発以外のところに工数を取られるのは嫌なものです。
探してみると色々なモックサーバがあるのですが、好みに合うものが見つからなかったので作ってみました。

欲しかった機能:

  • レスポンスヘッダを設定できる。
  • レスポンスを簡単に切り替えることが出来る。
  • リクエスト、レスポンスの内容を確認することができる。
  • (あると嬉しい) リクエスト内容によってレスポンスを切り替えることが出来る。

instant-mock

使い方

作ったモックサーバはこちらです。
https://github.com/arenahito/instant-mock

細かい説明は後にして、まずは動かしてみます。
Node.js 製なので、Node.js をインストールしてnpmが使えるようにしてください。
npmが使えるようになったら、下記コマンドでグローバルにインストールします。

npm install -g instant-mock

あとは、モックデータを格納する適当なディレクトリに移動して初期化&起動するだけです。

cd (お好きなディクトリ)
instant-mock init
instant-mock

無事に起動したら、ブラウザで http://localhost:3000 にアクセスしてみてください。下記のようなコンソールが表示されたら成功です。

init.png

右側に表示されているのが、instant-mock initコマンドで作成したサンプルのモックAPIです。
右端にはレスポンスを切り替えるためにセレクトボックスが表示されています。レスポンスの作り方は後ほど。

すべてのモックAPIは http://localhost:3000/mock 配下にマウントされますので、ブラウザやcurlで http://localhost:3000/mock/users にアクセスしてみてください。
JSONが返却されたらコンソールに戻りましょう。下記のようにリクエスト/レスポンスの内容が表示されています。

logs.png

API定義

モックAPIの定義ファイルは、mock ディレクトリ配下に用意します。
ディレクトリ名からURLパスが自動生成されます。mock/api-name/@METHOD というディレクトリであれば、METHOD: http://localhost:3000/mock/api-name にマッピングされます。METHOD は、get/post/put/patch/deleteからお好きなものをどうぞ。
ルートパラメータを使用したい場合は、$PARAM ディレクトリを作ればOKです。mock/api-name/$id/@get だと、GET: http://localhost:3000/mock/api-name/:id にマッピングされます。:id は可変ですね。

instant-mock init を実行するとサンプルの定義ファイルが出来ますので、参考にしてください。

リクエストパーサ

リクエストに対するレスポンスは、"parser-" で始まるYAML/JSファイルで定義します。
下記ファイルを作ってinstant-mockを再起動し、http://localhost:3000/mock/users にアクセスしてください。YAMLファイルで定義した内容が返却されます。

./mock/books/@get/parser-default.yml:

status: 200                   # Response status code.
headers:                      # Response headers.
  Content-Type: application/text
rawBody: 'test body'          # Response body.

レスポンスボディを別ファイルに記述

前節ではレスポンスボディをYAMLファイルに直接記述しましたが、下記のように別ファイルとすることも出来ます。
別ファイルを作った場合は、rawBody ではなく、body にファイル名を設定してください。

./mock/books/@get/body.json:

{
  "key": "value"
}

./mock/books/@get/parser-default.yml:

status: 200
headers:
  Content-Type: application/json
body: 'body.json'    # Response body file.

リクエスト内容によってレスポンスを切り替える

モックだし固定データを返せれば良いんだけど、リクエストに合わせて変えられると嬉しいな~ |ω・`)チラ
という方のために、簡易的にリクエストからレスポンスにマッピングする機能があります。

下記のように記述すると、ルーティングパラメータの id によってレスポンスを切り替えることが出来ます。
http://localhost:3000/mock/books/1 にアクセスすると "book 1"、http://localhost:3000/mock/books/3 だと404が返却されます。

./mock/books/$id/@get/parser-default.yml:

- if:
    params:
      id: 1
  then:
    rawBody: 'book 1'

- if:
    params:
      id: 2
  then:
    rawBody: 'book 2'

- then:
    status: 404

if には、params/query/bodyを指定することができます。
これらは "and" 条件となりますので、すべてに一致した場合に then で定義したレスポンスが返却されます。

  • params: ルートパラメータ
  • query: クエリ文字列パラメータ
  • body: ボディのJSONデータ

もっとすごいことがしたい

YAMLファイルの条件指定は簡易的なものです。条件は完全一致で "and" のみです。
もっとすごいことがしたい方は、YAMLではなくJavaScriptを使用することが出来ます。

作り方は簡単で、パラメータとしてリクエストオブジェクトを受け取り、レスポンス定義を返却する関数をexportするだけです。
リクエストオブジェクトは Express.jsRequest をそのまま渡していますので、煮るなり焼くなりお好きにどうぞ。

./mock/shelves/:id/@get/parser-default.js:

exports.default = function (req) {
  return {
    status: 200,
    headers: {
      'content-type': 'application/text',
    },
    rawBody: 'your book is ' + req.params.id,
  };
};

おわりに

単体テストだけでいきなり結合したら爆発したということにならないためにも、モックサーバを使ったテストをお勧めします。
対向サーバがエラーを返すデータを作れない (作るのが大変) という場合にも、モックサーバがあれば幸せになれます。
使えるものは使って手を抜きつつも、きっちりテストしましょう (・∀・)ノシ