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 側を書く前のテストとしてはとても書きやすいと思った。

More