- 更新日: 2014年4月21日
- RSpec
Rspec で Controller テストの準備編
Rails チュートリアルの説明通りに RequestSpec を中心に書くようにしていたのですが、ControllerSpec を書くべきケースに出くわしました。ということで、まずコントローラーのテストでユーザーをログインさせるために以下ドキュメントを参考にしました。
How To: Controllers tests with Rails 3 (and rspec)
— 環境 —
rails-4.0.1
rspec-rails-2.14.0
capybara-2.2.0
spec_helper.rb の設定
まず、spec_helper.rb に以下を追加。
spec/spec_helper.rb
1 2 3 4 |
RSpec.configure do |config| config.include Devise::TestHelpers, :type => :controller config.extend ControllerMacros, :type => :controller end |
ControllerMacros モジュールを作成
login_admin, login_user のメソッドを作成します。
spec/support/controller_macros.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
module ControllerMacros def login_admin before(:each) do @request.env["devise.mapping"] = Devise.mappings[:admin] admin = FactoryGirl.create(:admin) # sign_in(scope, resource) if admin is nested in user at factory. sign_in :user, admin end end def login_user before(:each) do @request.env["devise.mapping"] = Devise.mappings[:user] user = FactoryGirl.create(:user) sign_in user end end end |
ControllerSpec(コントローラーテスト)を作成
spec/controllers/some_controller_spec.rb
1 2 3 4 5 6 7 8 9 |
require 'spec_helper' describe SomeController do login_user it "should have a current_user" do expect(subject.current_user).not_to eq nil end end |
ControllerMacros および ControllerSpec は、ドキュメント通りの上述の書き方だと上手く動きました。
上手く動かなかった書き方
最初テスト側でログイン状態の融通を効かせようとして、以下のように書いていたのですが動作しませんでした。
spec/support/controller_macros.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
module ControllerMacros def login_admin @request.env["devise.mapping"] = Devise.mappings[:admin] admin = FactoryGirl.create(:admin) # sign_in(scope, resource) if admin is nested in user at factory. sign_in :user, admin end def login_user @request.env["devise.mapping"] = Devise.mappings[:user] user = FactoryGirl.create(:user) sign_in user end end |
spec/controllers/some_controller_spec.rb
1 2 3 4 5 6 7 8 9 10 11 |
require 'spec_helper' describe SomeController do before do login_user end it "should have a current_user" do expect(subject.current_user).not_to eq nil end end |
ControllerMacros から befor(:each) を省いて、テストのほうの before do でログインさせようとしていたのですが、以下のエラーが出て結局解決できなかった。以前もこれではまっていたのです…
1 2 3 4 5 |
Failure/Error: login_user NameError: undefined local variable or method `login_user' for #<RSpec::*** |
なのでドキュメント通り最初の方法で書いて、ユーザーがログインしていない状態(current_user が nil)のテストを書く時は、describe 文をネストせずに分けて login_user を書かないようにします。
- – 参考リンク –
- devise + Rspec でログイン状態のテストをしようとしたら動かなかった – 同じにやっても動かない
- Controller specs – RSpec Rails – RSpec – Relish
- Railsでテストを書いてみる(Rspec:Controller編) – KodaNote
- how to test params passed into a controller in rails 3, using rspec? – Stack Overflow
- RSpec の関連記事
- FactoryGirlをSpringと共に使う時の注意
- 複数モデルのpost :createをテストするRSpecコード(Controller Spec)
- RSpec3でTime.nowをスタブ化(stub)
- RSpecでJSONによるPOSTリクエストをテスト
- RSpec & Capybara の雑感
- RSpec+Capybaraで同名の複数要素の並び順をテストする
- RSpec3ではrails_helper.rbがrequireされる
- Capybara + Launchy で RSpec テストをブラウザで確認
- CapybaraのwithinをRSpecで使う
- Serverspec(RSpec)のテスト出力に色を付けて見やすくフォーマット
- 2件のコメント
役に立ちました!!
ありがとうございます!!
いえいえ^^どういたしまして!
こちらこそお役に立てて嬉しいです。