概要
RailsでController Specを書く際に、知っておくと便利なことをまとめました。
環境
- Ruby 2.3.1
- Ruby on Rails 5.0.0.1
Tips
ユーザーエージェントの切り替え
PCスマホで処理を切り替えるなど、ユーザーエージェントを参照して処理を行うactionをテストする場合には、次のようにユーザーエージェントを設定することでテストできます。
RSpec.describe HogeController, type: :controller do
describe "GET #index" do
context 'iPhoneの場合' do
it "returns http success" do
request.env["HTTP_USER_AGENT"] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53'
get :index
expect(response).to have_http_status(:success)
end
end
end
end
ちなみにデフォルトでは「Rails Testing」というユーザーエージェントが設定されています。
明示的にクエリパラメータとして渡す
パラメータに対応する静的URLがあるが、あえて、クエリパラメータでアクセスしたい場合には次のようにします。
Rails.application.routes.draw do
get '/hoge' => 'hoge#index'
get '/hoge/page-:page' => 'hoge#index'
end
RSpec.describe HogeController, type: :controller do
describe "GET /hoge/page-1" do
context '/hoge/page-1でアクセス' do
it "returns http success" do
get :index, params: {page: '1'}
expect(response).to have_http_status(:success)
end
end
end
describe "GET /hoge/?page=1" do
context '/hoge/?page=1でアクセス' do
it "returns http success" do
request.env['PATH_INFO'] = '/hoge/?page=1'
get :index, params: {page: '1'}
expect(response).to have_http_status(:success)
end
end
end
end
クエリパラメータを使っていたが、静的URLに移行したといった場合のリダイレクトなどのテストに必要になると思います。
ドメイン情報を含んだリダイレクト先のテスト
リダイレクト先のテストをするためには、redirect_toメソッドが用意されています。
redirect_toの使い方については、こちらのリンクに書かれています。
ここでは、上のリンクで説明されていない特殊なケースについて説明します。
同じRailsアプリケーション内で複数のドメインを使っている場合には、リダイレクト先にドメインを含んだパスを指定する必要がありますが、その際にredirect_toはドメインを自動的に補完してしまいます。
そういった場合には、次のようにドメインを明示的に指定すれば大丈夫です。
Rails.application.routes.draw do
get '/hoge/redirect' => 'hoge#redirect'
constraints(:host=> /fuga\.hoge\.com\.jp/) do
get '/hoge' => 'hoge#fuga_index'
end
end
RSpec.describe HogeController, type: :controller do
describe "GET /hoge/redirect" do
it "//fuga.hoge.com/hogeへのリダイレクト" do
subject {get :redirect }
expect(subject).to redirect_to('//fuga.hoge.com/hoge')
end
end
end
render_views
render_viewsは、その名の通りController Specを実行する際にViewのレンダリングをすることを指定するためのメソッドです。
これを指定しないとView内のエラーを拾うことができないので、基本的には設定することをお薦めします。
例えば、次のような、View内で未定義の変数を参照するといった明らかなバグを含んでいる場合であってもrender_viewsを記述しない場合にはテストが通ってしまいます。
RSpec.describe HogeController, type: :controller do
describe "GET /hoge" do
render_views
it "returns http success" do
get :index
expect(response).to have_http_status(:success)
end
end
end
<h1>Hoge#index</h1>
<p><%= hoge %>の一覧です。</p>