stripe-ruby-mockを剥がしていく
RubyのプロジェクトでStripeに関連するSpecを書く際に stripe-ruby-mock というgemを使っています。StripeのSDKのインターフェイスを再現してくれたり、インメモリでStripeの状態を管理してくれたりと非常に良くできているのですが、Stripeの機能が膨大すぎてメンテが追いついていないことから、rspecのモックでカバーするケースも増えてきていました。
stripe-ruby-mockにコントリビュートすることも考えたのですが、焼け石に水になりそうだったので、プレーンなrspecのモックに置き換えることを検討し始めました。
検討した方法
1. WebMockでSDKからのHTTPリクエストをモックする
stripe-ruby-mock は StripeMock.start を実行するとSDKから送信されるHTTPリクエストをモックしてレスポンスを返してくれます。これをWebMockに置き換えることを検討しましたが、レスポンスがかなり巨大でそれを用意・管理したりするのが大変なことから、いったんこのアイディアは却下しました。
2. SDKの振る舞いをモックする
HTTPレベルのモックではなく、SDKレベルでモックするアイディアです。
allow(Stripe::XXX).to receive(:xxx).and_return(response)
の形式でモックしていきます。
response
に関してはSDKにいくつかのルールがあり
- 単一のオブジェクトを返すレスポンス:
Stripe::XXX.construct_from()
- リストを返すレスポンス:
Stripe::ListObject.construct_from({ data: [] })
- 検索結果を返すレスポンス:
Stripe::SearchResultObject.construct_from({ data: [] })
※ data
には単一オブジェクトの配列を渡す。
のようにすることでSDKのインターフェイスを再現することができます。
ネストしたオブジェクトの作成
expanding_objects オプションを使い、レスポンスにネストしたオブジェクトが含まれる場合があります。このときも Stripe::XXX.construct_from()
を使い、APIリファレンスに従いネストした構造を記述すればOKです。
Webhookイベントの作成
こんな感じでモックを作成する。
Stripe::Event.construct_from(
id: "evt_12345",
type: event_type,
data: Stripe::StripeObject.construct_from(object: event_object)
)