今回はController編。導入編、Model編は下記からどうぞ。
Rails RSpecの基本 ~導入編~
Rails RSpecの基本 ~Model編~
なお、導入編ではRSpecのセットアップ、Model編ではFactoryGirlの導入及びFakerの導入について書いてあるので導入がない方はそちらから。
*ここでは上記の設定ありきです。
exampleを作成する
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'GET #show' do
it "assigns the requested article to @article"
it "renders the :show template"
end
end
マッチャを書いてテストをパスさせる
GETのテスト
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'GET #show' do
it "assigns the requested article to @article" do
article = create(:article)
get :show, id: article
expect(assigns(:article)).to eq article
end
it "renders the :show template" do
article = create(:article)
get :show, id: article
expect(response).to render_template :show
end
end
end
POSTのテスト
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'POST #create' do
it "saves the new contact in the database" do
expect{
post :create, article: attributes_for(:article)
}.to change(Article, :count).by(1)
end
it "redirects to articles#index" do
post :create, article: attributes_for(:article)
expect(response).to redirect_to articles_path
end
end
end
PATCHのテスト
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'PATCH #update' do
it "locates the requersted @article" do
article = create(:article)
patch :update, id: article, article: attributes_for(:article)
expect(assigns(:article)).to eq article
end
it "changes @article's attributes" do
article = create(:article)
patch :update, id: article, article: attributes_for(:article, title: 'hoge', content: 'hogehoge')
article.reload
expect(article.title).to eq("hoge")
expect(article.content).to eq("hogehoge")
end
it "redirects to articles_path" do
article = create(:article)
patch :update, id: article, article: attributes_for(:article)
expect(response).to redirect_to articles_path
end
end
end
DELETEのテスト
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'delete #destroy' do
it "deletes the article" do
article = create(:article)
expect{
delete :destroy, id: article
}.to change(Article,:count).by(-1)
end
end
end
beforeフックで共通処理をまとめる
先ほどの#showを例に取る
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
describe 'GET #show' do
it "assigns the requested article to @article" do
article = create(:article)
get :show, id: article
expect(assigns(:article)).to eq article
end
it "renders the :show template" do
article = create(:article)
get :show, id: article
expect(response).to render_template :show
end
end
end
共通パーツを切り出して、beforeでまとめる。
articleはインスタンス変数にする。
/spec/controllers/articles_controller_spec.rb
describe ArticlesController do
before :each do
@article = create(:article)
get :show, id: @article
end
describe 'GET #show' do
it "assigns the requested article to @article" do
expect(assigns(:article)).to eq @article
end
it "renders the :show template" do
expect(response).to render_template :show
end
end
end
認証を考える
ログイン認証をかけている場合は、そのままではテスト出来ない。
deviseを用いた認証は下記の記事を参考にすればうまくいった。
deviseを使ったコントローラのテスト
参考
Everyday Rails - RSpecによるRailsテスト入門
を参考にしております。詳細な説明・使い方を知りたい方はオススメです。
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」
RSpecに関しましてはこちらも参考になります。その1~その4まであります。