Railsのrequest-specからレスポンスを抽出して、サーバのレスポンスをモックできるgemを作った
明けましておめでとうございます!
正月中にswift覚えて、イケイケモバイルエンジニアに華麗な転身を遂げる予定でしたが結局swiftは1行も書きませんでした。
しかしswiftを代償に捧げた結果、Railsのrequest-specからレスポンスを抽出して、サーバのレスポンスをモックできるautomockというgemができました。
automock is 何
WebAPIに対しては、極力中のロジックに関与せず(モックも極力使わずに)、特定のリクエストを投げたら決まったレスポンスが返ることをブラックボックスにテストするのがいいよね、というベストプラクティスがあり、この形式で書かれたものはrequest-specと呼ばれています。 これに関しては以下の記事が詳しいです。
RSpecでRequest Describer - Qiita
このテストは実際にrequestを投げてresponseを受け取るので、HTTPで流れる情報の全てを扱うことができます。
Rspecには autodocという id:r7kamura さんの作ったgemがあって、これはrequest-specのテストを実行するとドキュメントが自動生成されるという最高のユーザ体験を提供してくれます。
このgemの発想は最高で、ドキュメントと実装の乖離は解消されて、何よりテストを書くモチベーションが格段に向上します。
autodocの「テストを書いたらドキュメントが生成される」という発想にインスパイアされて作ったのがautomockです。 これはRailsが返すレスポンスを奪い取って、request-specから抽出したレスポンスに置き換えることができます。
使い方
インストール方法などはドキュメントをご参照いただければ。 Rubyな世界でのインターフェースはautodocとほぼ一緒です。
responseを抽出すると、こんな感じでファイルができます。
$ ls -l automock/data/api/v1/users/ -rw-r--r-- 1 masato_noguchi staff 520 Jan 3 19:29 DELETE_receives_204.json -rw-r--r-- 1 masato_noguchi staff 535 Jan 3 19:27 GET_receives_200_and_users_json.json -rw-r--r-- 1 masato_noguchi staff 520 Jan 3 19:29 POST_receives_201.json -rw-r--r-- 1 masato_noguchi staff 520 Jan 3 19:29 PUT_receives_200.json
ファイルパスはAPIのパスで、ファイル名は method名 + it のタイトルになります。 もっと見やすい形式がある気がしてならないので、アドバイスください。
automockはプロキシサーバと、モック対象のレスポンスを管理する画面とでサーバを2つ起動します。 サーバを起動し、localhost:8000にアクセスすると管理画面を見ることができます。 (portは起動時の引数で変更可能)
左が未選択のファイルで、右が選択済みのファイルのリストになります。 (雑な感じのUIですみません。暇を見つけてもうちょいどうにかします。)
proxy serverはデフォルトで8001番で起動しています。
開発時はここにアクセスしていきます。
何も選択していない状態であれば、Railsのレスポンスがそのまま返ってきます。
例えば GET /api/v1/users
を例にとって見てみます。
全てを未選択にして、
レスポンスはこんな感じ。
今度はGET /api/v1/uesrs
選択状態にします。
そうすると、request-specから抽出したレスポンスが返却されるようになります。
動機とか狙いとか今後の展望とか
フロントエンド開発時にレスポンスをモックするという発想はかなり昔からあって、1年ぐらい前には僕はstubbyとかを使ってました。
しかしこの手法はあまり流行っていない感覚があって、モックデータを自前で用意する必要がある以上、実装との乖離が発生してしまい、メンテナンスコストがかかってしまうところが問題なのかなぁ、と思っています。
automockを使えば基本的にはrequest specを書いていれば、後は実行する時にボタンをぽちぽち押すだけになります。
SPAとWebAPIが全盛のこの時代においては、サーバサイドとクライアントサイドの境界線ははっきりしてきました。
機能開発やバグの修正時にも、サーバサイドとクライアントサイドを別々に実装していくことが多くなってきていて、ともすればサーバサイドとフロントエンドを開発する人は別だったりします。
そんな時に間を取りもつ係になりたい。人類の役に立ちたい。
今後の展望としては、現在uriしかマッチングのキーにしてないので、プログラマブルに条件を組めるようにしたいなー、とか、現状Railsしか対応してないけど他のフレームワークにも対応したいなー(そもそもProxy部分はnodejsで書いているのでRailsに依存していない)、とかざっくりいろいろあります。
まだドッグフーディングできてなくて、いっぱいバグありそう。 もし使ってみてくれた方いましたら、フィードバックいただけたら嬉しいです。