こんにちは!kossyです!
さて、今回はRailsAPIモードで認証機能周りのrequest_specでログイン・ログアウト状態を再現したい時の方法を
ブログに残してみたいと思います。
環境
Rails 5.1.6
Ruby 2.5.1
rspec 3.8.0
devise_token_auth 1.1.3
support直下にmoduleを定義したファイルを作成し、rails_helper.rbに読み込ませるだけ
supports直下にファイルを作成します。
spec/supports/authentication_helper.rb(名前は任意) module AuthenticaitionHelper HTTP_HELPERS_TO_OVERRIDE = [:get, :post, :patch, :put, :delete] # ログイン状態にする def login(user) @user = user @auth_token = @user.create_new_auth_token # devise_token_authのメソッド 参考: https://www.rubydoc.info/gems/devise_token_auth/0.1.37/DeviseTokenAuth%2FConcerns%2FUser:create_new_auth_token end # ログアウトする def logout @user = nil @auth_token = nil end # 参考: https://gist.github.com/blaze182/3a59a6af8c6a7aaff7bf5f8078a5f2b6 HTTP_HELPERS_TO_OVERRIDE.each do |helper| # 定数に対して繰り返し処理を実行 define_method(helper) do |path, **args| # def get(path) のようなメソッドを動的に定義 add_auth_headers(args) # privateメソッドの呼び出し args == {} ? super(path) : super(path, **args) # argumentsが空ハッシュなら定義元のメソッドを実行、空でなければ定義元のメソッドをargumentsを引き連れて実行 end end private # tokenをセットするprivateメソッド def add_auth_headers(args) return unless defined? @auth_token # @auth_tokenが定義されていなければ処理終了 https://www.xmisao.com/2014/03/30/checking-if-a-variable-is-defined.html args[:headers] ||= {} # args[:headers]がnilなら{}を代入 args[:headers].merge!(@auth_token) # args[:headers]に@auth_tokenを代入 end end
作ったモジュールをrails_helper.rbで読み込む記述を追加します。
RSpec.configure do |config| 省略 Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } #support directoryをrequire config.include AuthenticationHelper, type: :request #type: :requestのときにRequestHelperをinclude end
これで例えばFactoryBot等でuserを定義している場合、
user = FactoryBot.create :user login user
等でログイン状態を再現できます。
参考にさせていただいた記事
type: :requestのテストでsign_in/sign_outする - Qiita