テスト方法は GitHub の Wiki を参考にしていますが内容は少し変更しています。
ログインメソッドの作成
まずはspec/support/controller_macros.rb
にログイン用のモジュールを作成します。
login_admin
のメソッドはここでは削除しました。必要なら作成してください。
user.confirm!
はメソッドが既に削除されているため使用できません。代わりにconfirm
メソッドを使用するか、FactoryGirl の User にconfirmed_at { Time.current }
を追加します。
ruby on rails - NoMethodError: undefined method `confirm!' for #<User - Stack Overflow
before(:each)
も spec ファイル側で使いたいのでこのモジュールからは削除しています。最後に User モデルを引数で指定できるように変更しました。
module ControllerMacros def login_user(user=nil) @request.env["devise.mapping"] = Devise.mappings[:user] user ||= FactoryGirl.create(:user) sign_in user end end
設定ファイルの変更
spec/rails_helper.rb
かspec/support/devise.rb
を新しく作成して次の設定を追加します。テスト用のヘルパーと先程作ったログイン用のモジュールを読み込みます。
RSpec.configure do |config| config.include Devise::Test::ControllerHelpers, :type => :controller config.include ControllerMacros, :type => :controller end
spec/support
ディレクトリ内のファイルを読み込むようにしていなければspec/rspec_helper.rb
に次の一文を追加して下さい。コメントアウトされていると思います。
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
ログイン用のモジュールを読み込む設定でextend
からinclude
に変えている理由は spec のbefore(:each)
で呼び出したいためです。
RSpec.configure の extend 、 include はどうなっているのか - Qiita
RSpecの実行サンプル
実際に動作する spec ファイルが以下の通りです。User は引数で渡さなければ生成するようにしているため今回は省略しています。
require 'rails_helper' RSpec.describe UsersController, type: :controller do describe 'GET #index' do context 'with assign all users' do before do login_user get :index end it { is_expected.to have_http_status :success } it { is_expected.to render_template :index } end end end
実行結果です。
$ ./bin/rspec spec/controllers/users_controller_spec.rb UsersController GET #index with assign all users should respond with 200 should render template index Finished in 0.70331 seconds (files took 3.8 seconds to load) 2 examples, 0 failures
current_userのモックを作る
今回の認証を通してからのテストとは別の話しですが、Device に含まれるcurrent_user
メソッドのモックを作成して指定したユーザーを返すようにするには次のようにします。
let(:user) { FactoryGirl.create(:user) } before do allow(controller).to receive(:current_user).and_return(user) end