コンユウメモ @kon_yu

作ったガラクタとか、旅行とかの話

deviseで認証しているログイン必須のRspec controllerテスト

Railsの認証系の定番ライブラリdeviseでコントローラをテストする場合、 ログインした状態のテストをしたい場合の対処方法を確立した。

公式のが一番確実だけれども、公式の方法だと作ったユーザオブジェクトの属性を変更することが出来ない。 例) 有料ユーザや無料ユーザの振る舞いや、退会ユーザの場合など

参考: How To: Test controllers with Rails 3 and 4 (and RSpec) https://github.com/plataformatec/devise/wiki/How-To:-Test-controllers-with-Rails-3-and-4-(and-RSpec)

そこで上記リンクのものを修正/拡張した

ログイン用のモジュールを作る

spec/support/controller_macros.rb にログイン用のモジュールを作る

controller_macros.rb

module ControllerMacros
  def login_admin(admin)
    @request.env["devise.mapping"] = Devise.mappings[:admin]
    sign_in admin
  end

  def login_user(user)
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user.confirm!
    sign_in user
  end
end

helperファイルに設定を追加

Rspec2ならspec_helper、Rspec3ならrails_helperにdeviseを読んであげる

rails_helper.rb

#deviseを読み込ませる
require 'devise'

RSpec.configure do |config|

 # deviseのテストヘルパーをロードする
  config.include Devise::TestHelpers, :type => :controller
 # 作成したログインモジュールを追加する
  config.include ControllerMacros, :type => :controller
end

specファイル例

xxx_controller_spec.rb

require 'rails_helper'

RSpec.describe XxxxController, :type => :controller do
  describe "GET #show" do
    # userをFactoryGirlで作る
    let(:user) { FactoryGirl.build(:user) }
  # 作ったユーザでログインする
    before do
      login_user user
    end

    it "can get it" do
      get :show, id: 1
      
      # 出力結果
      p response
    end
  end
end

refs:

Featureテストの場合はこちらを参考にすると良い * "Rails + RSpec + Capybara で Devise での認証ログインが必要なインテグレーションテスト(RequestSpec)を行う" http://easyramble.com/request-spec-on-devise-login.html