背景
フレンドリーフォワーディングのテストをRSpecで行いたい。
編集ページのpathをsessionがちゃんと保持しているのかを確認するために、編集ページのpathとsession[:forwarding_url]
が一致していることをテストしたいが、sessionメソッドを使おうとしたらエラーが発生し解決に時間がかかったので、備忘録として投稿します。
失敗したコード
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なんてメソッドはないと怒られました。
参考にさせていただいた記事
こちらの記事同様、rails_helper.rb
でsessionメソッドの上書きを行いました。
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の取得形式が異なるため、エラーが起こってる。
エラー解消
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
無事テストがパスしました!
間違い等ございましたら、ご指摘いただけると幸いです!