LoginSignup
1
1

More than 1 year has passed since last update.

RSpecでsessionメソッドを使えるようにするには?

Posted at

背景

フレンドリーフォワーディングのテストをRSpecで行いたい。
編集ページのpathをsessionがちゃんと保持しているのかを確認するために、編集ページのpathとsession[:forwarding_url]が一致していることをテストしたいが、sessionメソッドを使おうとしたらエラーが発生し解決に時間がかかったので、備忘録として投稿します。

失敗したコード

spec/system/users_edit_spec.rb
RSpec.describe "Users", type: :system do
  describe 'PATCH /users' do
    let(:user) { FactoryBot.create(:user) }
.
. #中略
.
    it 'ログインすると、編集画面にリダイレクトされる' do
      visit edit_user_path(user)
     #↓ここでフレンドリーフォワーディングのテストをしている
      expect(session[:forwarding_url]).to eq edit_user_path(user)
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_button 'ログイン'
      visit current_path
      expect(page).to have_current_path edit_user_path(user)
.
. #中略
.
    end
  end
end

実行結果

Failures:

  1) Users PATCH /users ログインすると、編集画面にリダイレクトされる
     Failure/Error: expect(session[:forwarding_url]).to eq edit_user_path(user)
     
     NoMethodError:
       undefined method `session' for nil:NilClass
     
             @request.session
                     ^^^^^^^^
     # ./spec/system/users_edit_spec.rb:45:in `block (3 levels) in <top (required)>'

Finished in 1.59 seconds (files took 1.75 seconds to load)

sessionなんてメソッドはないと怒られました。

参考にさせていただいた記事

 RSpec RequestSpecでsessionを利用する 

こちらの記事同様、rails_helper.rbでsessionメソッドの上書きを行いました。

rails_helper.rb
RSpec.configure do |config|
  # ...

  # テストケース共通の事前処理
  config.before(:each) do

    # let(:rspec_session) で指定された値を セッションの初期値とします
    session = defined?(rspec_session) ? rspec_session : {}

    # destroyメソッドを実行してもエラーにならないようにします(必要であれば)
    session.class_eval { def destroy; nil; end } 

    # sessionメソッドを上書き
    allow_any_instance_of(ActionDispatch::Request).to receive(:session).and_return(session)
  end
end

上記の通り上書きを行なった上で、
expect(session[:forwarding_url]).to eq edit_user_path(user)

expect(RSpec.configuration.session[:forwarding_url]).to eq edit_user_path(user)
に書き換え、再度テスト実行。

実行結果

Failures:

  1) Users PATCH /users ログインすると、編集画面にリダイレクトされる
     Failure/Error: expect(RSpec.configuration.session[:forwarding_url]).to eq edit_user_path(user)
     
       expected: "/users/2362/edit"
            got: "http://www.example.com/users/2362/edit"
     
       (compared using ==)
     # ./spec/system/users_edit_spec.rb:45:in `block (3 levels) in <top (required)>'

Finished in 1.52 seconds (files took 1.67 seconds to load)
3 examples, 1 failure

sessionのエラーはクリア!pathの取得でエラーが起きてる。
RSpec.configuration.session[:forwarding_url]edit_user_path(user)のpathの取得形式が異なるため、エラーが起こってる。

エラー解消

spec/system/users_edit_spec.rb
RSpec.describe "Users", type: :system do
  describe 'PATCH /users' do
    let(:user) { FactoryBot.create(:user) }
.
. #中略
.
    it 'ログインすると、編集画面にリダイレクトされる' do
      visit edit_user_path(user)
     #  "'http://www.example.com' +" を追加することで文字列を=になるように変更
      expect(RSpec.configuration.session[:forwarding_url]).to eq 'http://www.example.com' + edit_user_path(user)
      fill_in 'Email', with: user.email
      fill_in 'Password', with: user.password
      click_button 'ログイン'
      visit current_path
      expect(page).to have_current_path edit_user_path(user)
.
. #中略
.
    end
  end
end

無事テストがパスしました!
間違い等ございましたら、ご指摘いただけると幸いです!

1
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1