my_api_client v0.13.0 をリリースしました🚀
つい先日、v0.12.0 をリリースしたばかり ですが、 v0.13.0 をリリースしましたので、含まれる PR の内容について解説していきます。 より詳しい使い方は README.jp.md をご参照ください。
#180 Stub response on raising error (@ryz310)
今回はこの PR のみの更新です。 仕事で spec 書いてる最中に「API リクエストで例外が発生した際にレスポンス内容を保存する処理のスタブ化できないじゃん」ってなって作りました。
my_api_client
では作成した API Client クラスを stub_api_client
または stub_api_client_all
というメソッドでスタブ化できます。
例えば以下のような ExampleApiClient
というクラスを定義した時:
class ExampleApiClient < MyApiClient::Base endpoint 'https://example.com' error_handling status_code: 400..499, raise: MyApiClient::ClientError error_handling status_code: 500..599, raise: MyApiClient::ServerError # GET https://example.com/path/to/resouce def request get 'path/to/resouce' end end
stub_api_client_all
を実行すると ExampleApiClient
のインスタンスが全てスタブ化されるようになります。
以下の例だと、 #request
を実行した時、API から { "message": "Hello world!" }
という JSON が返ってきた時と同じ振る舞いをするようになります。
stub_api_client_all( ExampleApiClient, request: { response: { message: 'Hello world!' } } ) api_client = ExampleApiClient.new response = api_client.request response.message # => 'Hello world!'
で、 error_handling
でステータスコードが 400..499
の時は MyApiClient::ClientError
という例外が発生する、という定義になっているのですが、このような例外が発生した時のテストを書くために、 raise
のスタブ化も出来るようになっています。
stub_api_client_all( ExampleApiClient, request: { raise: MyApiClient::ClientError } ) begin api_client = ExampleApiClient.new response = api_client.request rescue MyApiClient::ClientError puts '4xx error!' end
大抵の場合、これらのスタブ化ができれば問題ないのですが、例外発生時のレスポンスを見たい、というケースも無くはないかと思います。
仕様として、例外インスタンスの #params
や #matadata
というメソッドからリクエストパラメータとレスポンスパラメータを参照できるようになっています。
従来のスタブ化メソッドでも一応指定できなくはなかったんですが、結構手間だったので raise
オプションの指定を以下のように拡張しました。
raise
と一緒に指定した response
が API のレスポンスとして返されて、それが例外として処理された、というスタブ化になります。
stub_api_client_all( ExampleApiClient, request: { raise: MyApiClient::ClientError, response: { error_code: 10 } } ) begin api_client = ExampleApiClient.new response = api_client.request rescue MyApiClient::ClientError => e e.params.response.data.error_code #=> 10 end
my_api_client
は内部で Sawyer を使っています。
e.params.response
が Sawyer::Response
をそのまま返しているので、Sawyer::Response#data
からレスポンスボディを参照できます。
Sawyer::Response#data
では、レスポンスの JSON を OpenStruct) のようにメソッドアクセスできるように変換してくれます。
ただし、 V1.0.0
で Sawyer
の依存を無くしたいと考えているので、いずれ #data
を挟む書き方は変更になるかもしれません。
一応こういう使い方もできますよ、という新機能でした。