トップ «前の日記(2016-07-18) 最新 次の日記(2016-07-22)» 編集

2016-07-20 [長年日記]

_ webmockとpactのmock serviceの違い

実はこれまで webmock を使う必要がなかったので試しに API client を書く際に webmock でテストを書いてみた。そんで先日書いてみた Pact の mock service と比べてみた。

それぞれ GitHub 上の README より抜粋したコードを貼りつつメモ。

webmock

GitHub - bblimke/webmock: Library for stubbing and setting expectations on HTTP requests in Ruby.

stub_request(:post, "www.example.com").
  with(body: "abc", headers: { 'Content-Length' => 3 })

webmock は元のクライアントに一切手を加える必要がないのが特徴。

  • その代わりに request 先を正確に指定しないといけない
  • サンプルには書かれていなかったけど User Agent も正しく Header で指定しないとダメっぽい

Pact service consumer

GitHub - realestate-com-au/pact: Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.

     animal_service.given("an alligator exists").
       upon_receiving("a request for an alligator").
       with(method: :get, path: '/alligator', query: '').
       will_respond_with(
         status: 200,
         headers: {'Content-Type' => 'application/json'},
         body: {name: 'Betty'} )

Pact の mock service は localhost で受け付けるのが前提。

  • consumer の機能で endpoint を切り替える
  • クライアント側のテストだけを考えると service_name も provider state ( given ) も description ( upon receiving ) も RSpec なり Minitest なりのメタデータ以外に指定しないといけないのが面倒
  • request / response はいい具合に抽象化しやすい
    • response を {} と書くとその内容まではチェックしない
    • Pact.each_like({}) とすれば {} の個数もチェックしない

webmock の方がまだまだポピュラーではあると思うが、サービス同士のテストにはやはり Pact の方が書きやすいように思う。Pact は最初の設定(名前決めなど)以外の実際の mocking の部分は結構書きやすいし、response body を厳密に決める必要がないので、provider 側を書く前のテストとしてはとても書きやすいと思った。

Tags: Ruby WebAPI

_ RailsのCでもVでもない場所でアプリのURIを扱う方法

API を実装していく際にリンク先の URI も加えてあげたい*1場合、どこかで URI を生成する必要がある。

Grape で API を書く場合、提供される機能はあくまで endpoint 周りであって、アプリの内部実装は自分でなんとかする必要がある。Grape から使えるとしたら Rails の C でも V でもない場所にせざるを得ない。ということで C でも V でもない場所で URI を扱う方法を調べてみた。

Can Rails Routing Helpers (i.e. mymodel_path(model)) be Used in Models? - Stack Overflow

ということで

Rails.application.routes.url_helpers

を include すれば使えそうだが、その際 include する人は module でなく class でないとダメ っぽい。

これは C や V で利用することを前提に url_for() ができあがっているからか、もしくは自分が独自に作った Helper が super な url_for() を呼び出している際に何かの依存を踏んでいるからかもしれない。ちょっとよく分かっていないけど少なくとも class で include されるようにしておけば安定して動くことが分かった。

[20160731 追記] こんな記事があった。ほぼ考えてることそのまんまだった。

RailsのAPIにHATEOASを散りばめてみる : RESTの拡張、HATEOASの詳解と実装例 | プログラミング | POSTD

*1 HATEOASですね