💭
stripe ruby mockを使う
導入編
- 2021/12/7現在の最新バージョンは3.1.0.rc3のようです、基本的にはこれより上のバージョンを使うのをオススメします
- ドキュメント通りにgemをインストールすると3.0.1が入りますが個人的に試した時はこのバージョンだとArgment Errorが出てしまいました、バージョンを上げると解決しました
- ※コアコントリビュータがおらず安定してないように見えるので欲しい機能がないなどは十分にあり得ます
基本編
- 基本的には↓のような記述を追加するだけでモッキングできます、stripe_helperは便利メソッドを提供してくれるヘルパで、例えば
stripe_helper.generate_card_token
とすると簡単にcard tokenを作ったりなどできます- test_helperが使えるメソッドはこちらから一覧できます
let(:stripe_helper) { StripeMock.create_test_helper }
before { StripeMock.start }
after { StripeMock.stop }
- stripe-ruby-mockを使えば、仮にPaymentIntentオブジェクトを作った前提でテストを走らせたい時など以下のようなテストコードになるイメージです、allow~receiveなどを使って自前でモッキングするのに比べるとかなりシンプルです
before {
StripeMock.start
# stripeのPaymentIntentオブジェクトを作成
@payment = Stripe::PaymentIntent.create({amount: 100, currency: "JPY"})
charge.update!(provider_id: @payment.id)
}
after { StripeMock.stop }
context "payment_idからchargeの取得テスト" do
it "success" do
expect {
post api_fetch_charge_path, params: { payment_id: @payment.id }
}.to be
end
end
応用編
- エラーを起こしたい場合
- カード系のエラーの場合
-
prepare_card_error
メソッドを使うことができます、第一引数でエラーの内容を第二引数でエラーのおこるタイミングを指定できます
-
- 独自のエラーを発生させたい場合
-
prepare_error
メソッドを使うことができます、第一引数で引き起こすエラーを、第二引数でエラーの起こるタイミングを指定できます - 例えばPaymentIntentのcapture時にStripe::StripeErrorというエラーを引き起こしたい場合↓のようになります
-
:capture_payment_intent
はここから確認できます、このようにrequest_handlersディレクトリ以下の各ファイルの中から具体的な第二引数の名前は辿ることができます
-
-
- カード系のエラーの場合
before do
StripeMock.prepare_error(Stripe::StripeError.new("unknown reason"), :capture_payment_intent)
end
- integrationテストを行いたい場合
- StripeMock.startしてStripeMock.stopするのは便利ですがテストケースが終わると作成したStripeオブジェクトが消えてしまいます、integrationテスト時などはそれだと困る場合もあるのでモックサーバーを動かしてデータを一時的に永続化できるようです
- https://github.com/stripe-ruby-mock/stripe-ruby-mock#running-the-mock-server
- PaymentIntentオブジェクトなど状態を持つオブジェクトはどの状態を初期値として生成するのかコントロールしたいかと思います、ドキュメントにはオプションまで詳しくは載ってないのでソースコードを読むことをオススメします
- 例えばPaymentIntentを
status: requires_action
の状態で生成したい場合amountパラメータに3184を渡す必要があるようです、金額も¥3,184になってしまうので若干不服ですがこれでrequired_actionのデータを生成できます - その他のパラメータも生成時に渡してあげることで結構柔軟にstripeオブジェクトを生成できたりします、例えば普通にPaymentIntentを作成した場合reviewパラメータの値はnilが返ってきますが
Stripe::PaymentIntent.create({amount: 100, currency: "JPY", review: {closed_reason: "refunded_as_fraud"}})
と通常のパラメータに加えてreviewパラメータを渡して作成すると意図通りのオブジェクトを生成できます- ちなみに↑の例のreviewパラメータはPaymentIntentのAPI自体のパラメータではないのでStripeサーバーに向けて同じようにコールするとエラーになります
- 例えばPaymentIntentを
まとめ
- ぼちぼち柔軟な感じで基本的には導入するのがいいかと思いました、がやっぱり全てのテストケースに対応できる感じではないのでallow~receiveとの併用にはなりそうです
- もしくはフォークして自分達用に修正してもいいかもとも思いました(例えばPaymentIntentの生成処理は結構柔軟性に欠けててつらみって感じでした)
Discussion