8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】PAY.JPによる決済機能のモックを活用したコントローラーテスト

Last updated at Posted at 2020-02-01

はじめに

PAY.JPのAPIを用いた決済機能を実装した際にコントローラーの単体テストを実装しました。 PAY.JPを使用した機能においてテストを実施する場合、ダミーレスポンスを作る対応が必要とのことで、カード情報取得のレスポンスをモックで擬似的に再現したので実装方法をシェアします。

開発環境

Ruby 2.5.1
Rails 5.0.7.2
RSpec 4.0
factory_bot 5.1.1

モックとは

モックは以下のような定義となります。

  • 本物のふりをする偽物のプログラム
  • テスト用の影武者として働くオブジェクト

モックの定義については下記記事を参考にさせていただきました。

使えるRSpec入門・その3「ゼロからわかるモック(mock)を使ったテストの書き方」
【Ruby on Rails】RSpecにおけるモックとスタブの基本事項メモ【プログラミング学習開始142日目】

実装手順

PAY.JPの導入が完了していることを前提としています。
PAY.JPの導入は下記記事を参考にさせていただきました。
Payjpでクレジットカード登録と削除機能を実装する(Rails)」

テスト対象の機能

購入確認画面などでPAY.JPの機能で登録したクレジットカードの情報を取得し表示させたい場合の機能を対象としています。

スクリーンショット 2020-01-31 20.10.39.png

コントローラーのサンプルコード

app/controllers/purchase_controller.rb
  def show
    @image = @product.images.first
    Payjp.api_key = ENV["PAYJP_PRIVATE_KEY"]
    customer = Payjp::Customer.retrieve(@card.customer_id)
    @default_card_information = customer.cards.retrieve(@card.card_id)
    @address = Address.find_by(user_id: current_user)
  end

モックのサンプルコード

Payjp::Customerのレスポンスを下記にように擬似的に作ります。
外部APIから取得しているトークンの内容を確認してモックからのレスポンスとして記述しています。
モックの作り方は、下記記事のPayjp::Charge.createのモックを参考にさせていただきました。
Rails で Payjp を使って決済システムを導入する

spec/support/payjp_mock.rb
module PayjpMock
  def self.prepare_customer_information # Payjp::Customerのレスポンスモック
    {
      "id": "cus_ca9d1d98900ec1f2595aebefd9a6",
      "cards": {
        "count":1,
        "data":[{
          "id":"car_a96c76b044d7ae21439d7b9840b7",
          "address_city":nil,
          "address_line1":nil,
          "address_line2":nil,
          "address_state":nil,
          "address_zip":nil,
          "address_zip_check":"unchecked",
          "brand":"Visa",
          "country":nil,
          "created":1578830630,
          "customer":"cus_ca9d1d98900ec1f2595aebefd9a6",
          "cvc_check":"passed",
          "exp_month":12,
          "exp_year":2020,
          "fingerprint":"e1d8225886e3a7211127df751c86787f",
          "last4":"4242",
          "livemode":false,
          "metadata":{},
          "name":nil,
          "object":"card"
          }],
          "has_more":false,
          "object":"list",
          "url":"/v1/customers/cus_ca9d1d98900ec1f2595aebefd9a6/cards"
        },
      "created": 1578830631,
      "default_card": "car_a96c76b044d7ae21439d7b9840b7",
      "description": nil,
      "email": nil,
      "livemode": false,
      "metadata": {},
      "object": "customer",
      "subscriptions": {
        "count":0,
        "data":[],
        "has_more":false,
        "object":"list",
        "url":"/v1/customers/cus_ca9d1d98900ec1f2595aebefd9a6/subscriptions"
      }
    }
  end
end

モックの呼び出し

モックを使用したいテストコードで下記のようにモックを呼び出します。

sample.rb
allow(Payjp::Customer).to receive(:create).and_return(PayjpMock.prepare_customer_information)

コントローラーテストのサンプルコード

実際のテストコードでは下記のように呼び出します。
なお、本サンプルコードはfactorybotを使用しています。

spec/controllers/purchase_controller_spec.rb
require 'rails_helper'
describe PurchaseController, type: :controller do
  let(:user) { create(:user) }
  let(:card) { create(:card, user_id: user.id) }
  describe 'GET #show' do
      context 'ログイン時' do
      before do
        login user
      end
      it "showアクションのページに遷移するか" do
        allow(Payjp::Customer).to receive(:create).and_return(PayjpMock.prepare_customer_information)
        product = create(:product)
        get :show, params: { id: product,card: card}
        expect(response).to render_template :show
      end
    end
  end
end

まとめ

モックを用いることで外部APIからのレスポンスを擬似的に作ることできました。

参考記事

使えるRSpec入門・その3「ゼロからわかるモック(mock)を使ったテストの書き方」
【Ruby on Rails】RSpecにおけるモックとスタブの基本事項メモ【プログラミング学習開始142日目】
Rails で Payjp を使って決済システムを導入する

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?