Posted at

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

More than 3 years have passed since last update.


概要

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