📝

【RSpec】deviseのsign_inヘルパーを使う方法

に公開

はじめに

こんにちは!Koheiと申します。
今回は 認証機能にdeviseを使っているRailsアプリケーションで、RSpecでログイン状態をテストする際の内容について、私も躓いた点も含めてまとめたいと思います。
初学者のため、内容に間違い等ありましたら、優しく教えていただけますと幸いです。

対象の読者

  • Railsでアプリケーションを作成している。
  • 認証機能にdeviseを使っている
  • テストはRspecを使用している。(minitestではない)
  • deviseのテストヘルパーがうまく使えず、お手上げな方

参考

https://github.com/heartcombo/devise?tab=readme-ov-file#integration-tests
https://qiita.com/kazuya_minei109/items/b3c54a55c797ff04593e

本編

つまづいたポイント

https://qiita.com/kazuya_minei109/items/b3c54a55c797ff04593e
上記の記事を参考に、下記のRSpecファイルを書きました。

spec/requests/users_spec.rbrequire 'rails_helper'
RSpec.describe "Users" do
  it "ログインしたら、飛ばしたいページに飛ぶ" do
    @user = FactoryBot.build(:user)
    sign_in @user
    get XXXXXXX_path #サインイン後に飛ばしたい先のpathを記入する
    expect(response).to have_http_status(200)
  end
end

FactoryBotでユーザーを作成(これは個人の設定もあるので省略)し、deviseのヘルパーであるsign_inでログインさせ、任意のパスにGETリクエストを送る。そして、ステータスコードが200(成功)で返ってくることを期待する、というごく一般的なテストです。

そして、deviseに備え付けられているsign_inヘルパーを使用するため、spec/rails_helper.rbにも下記を記載。

spec/rails_helper.rb
RSpec.configure do |config|
  # Deviseのテストヘルパー
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Devise::Test::IntegrationHelpers, type: :system
  config.include Devise::Test::IntegrationHelpers, type: :request
end

「これで完璧!」と思いましたが、、、、テストを実行するとエラーを吐き出しました。

Terminal
Failures:

  X) Users ログインしたら、indexページに飛ぶ
     Failure/Error: sign_in @user
     
     NoMethodError:
     undefined method `sign_in' for #<RSpec::ExampleGroups::Users: ...>

sign_inメソッドが見つからない・・・?????

理由がわからず、公式ドキュメントなどを翻訳したり、いろんな技術記事を見たりしたのですが、
結果的に、下記で解決しました。(筆者はここで2時間消費した模様)

解決方法:テストファイルにtype: :requestを明記する

どうやら、rails_helper.rbで設定を有効にしただけでは不十分で、テストファイル自体がrequest specであることをRSpecに明示的に伝える必要があるようでした。

spec/requests/users_spec.rb
require 'rails_helper'

# RSpec.describeの引数に`type: :request`を追加
RSpec.describe "Users", type: :request do
  # ...
end

これでsign_inメソッドは無事に認識されるようになりました!やったね!
(たったこれだけなんかい!悔しい!)

おわりに

超短い記事で恐縮ですが、この記事で同様のエラーが解決できたなら幸いです・・・!
以上、おつかれさまでした!

Discussion