💭

stripe ruby mockを使う

2022/04/25に公開

https://github.com/stripe-ruby-mock/stripe-ruby-mock

導入編

  • 2021/12/7現在の最新バージョンは3.1.0.rc3のようです、基本的にはこれより上のバージョンを使うのをオススメします
  • ※コアコントリビュータがおらず安定してないように見えるので欲しい機能がないなどは十分にあり得ます

基本編

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サーバーに向けて同じようにコールするとエラーになります

まとめ

  • ぼちぼち柔軟な感じで基本的には導入するのがいいかと思いました、がやっぱり全てのテストケースに対応できる感じではないのでallow~receiveとの併用にはなりそうです
    • もしくはフォークして自分達用に修正してもいいかもとも思いました(例えばPaymentIntentの生成処理は結構柔軟性に欠けててつらみって感じでした)

Discussion