LoginSignup
3
3

More than 5 years have passed since last update.

grapeで作成したAPIのconcernモジュールのRSpecを書く方法

Posted at

概要

APIで共通の処理がある場合に、concernsディレクトリ以下のファイルに共通処理を書きDRYにしたい。
そのときにRSpecをどう書くかというお話です。
APIだけでなく、controllerの場合でも同様の方法が使えます。

方法

API(or controller)のconcernモジュールのテストで困るのは、エンドポイントをどうするかという点です。

方法としては、

  • モジュールをincludeしているAPIそれぞれにRSpecを書く
  • モジュールをincludeしているAPIのうち代表してひとつにのみRSpecを書く
  • 一般的なAPIをテストの時にのみ定義して、その一般的なAPIに対してRSpecを書く。

といったものがあるかと思いますが、今回は最後の方法を紹介します。

大まかに、以下の手順で行います。

  1. RSpecの中でfakeのAPI、エンドポイントを作成する
  2. fakeのAPIに当該モジュールをincludeする
  3. そのエンドポイントに対してリクエストを送りモジュールのテストをする

具体例

以下はinternalなAPIの認証のための処理で、正しいトークンを送っていない場合にBadRequestを発生させるモジュール。
このような処理はinternalなAPI全てで必要になるため、concerns以下に切り出している。

app/api/concerns/application_token_error_handler.rb
module ApplicationTokenErrorHandler
  extend ActiveSupport::Concern
  included do
    before do
      if params[:application_token] != Settings.application_token
        raise ActionController::BadRequest.new("Invalid application token #{params[:application_token]}")
      end
    end
  end
end

これに対するRSpecは以下のように書けます。
ポイントはRSpecの中で一般的なanonumousというエンドポイントを作成して、そこにリクエストを送るということです。

spec/requests/api/concerns/application_token_error_handler_spec.rb
require 'rails_helper'

describe ApplicationTokenErrorHandler, type: :request do
  before do
    # 1. fakeのAPIクラスとエンドポイントを定義
    class FakeApi < Grape::API
      # 2. テストしたいモジュールをincludeする
      include ApplicationTokenErrorHandler
      resources :anonymous do
        params do
          requires :application_token, type: String
        end
        get '/' do
          return status 200
        end
      end
    end

    # APIのルーティングを行うクラスにmountする(詳細は記事の範囲外なので省略)
    class API < Grape::API
      mount FakeApi
    end

    # 3. 上で定義したエンドポイントをリクエストする
    get '/anonymous', { application_token: application_token }
  end

  # テスト終了後に定義した定数を削除する
  after { Object.send :remove_const, :FakeApi }

  #
  # あとはいつも通りのAPIのテスト
  #

  # 正しいapplication_tokenをパラメタにしてリクエストした場合は200になる
  context 'application_token is right' do
    let(:application_token) { Settings.application_token }
    it { expect(response.status).to eq 200 }
  end

  # application_tokenが間違っている場合は400になる
  context 'application_token is mistaken' do
    let(:application_token) { 'invalid_token' }
    it { expect(response.status).to eq 400 }
  end
end

参考

grapeによるAPIの作成方法。
http://qiita.com/anoworl/items/756f01cc3d188ebad139

Controllerのconcernsモジュールをテストする例。
http://stackoverflow.com/questions/22055889/how-to-test-a-controller-concern-in-rails-4

3
3
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
3
3