rails初学者です。
RSpecでコントローラーのテストを実装するにあたり、新規投稿画面にアクセスした場合(newアクション)のテストをログイン/非ログイン状態で分岐させたく、方法を調べたので備忘録としてまとめました。
初学者向けの内容になっています。
環境
Ruby 2.6.5
Rails 6.0.3
以下インストール済み
Devise 4.7.3
RSpec 4.0.0
FactoryBot
前提条件
deviseのauthenticate_userを使って、postコントローラーのnewアクションに非ログイン状態でアクセスすると、ログイン画面にリダレクトされるようにしています。
class PostsController < ApplicationController
before_action :authenticate_user!, only: [:new]
~中略~
def new
@post = Post.new
end
~中略~
end
こちらの機能をテストしていきます。
Postsコントローラーテスト
RSpecでDeviseを使えるようにする。
RSpec.configure do |config|
~中略~
#下のコードを追記
config.include Devise::Test::IntegrationHelpers, type: :request
end
こちらのコードをrails_helper.rbに記述することで、requestテスト時にdeviseのヘルパーを呼び出すことができます。
テスト用ユーザーデータを用意
FactoryBotを使ってユーザーのテスト用データを用意します。
FactoryBot.define do
factory :user do
email { "test@example.com" }
password { "123456" }
password_confirmation { password }
end
end
ユーザーモデルにnameカラムなどを追加している場合は追加したカラムのデータも記述します。
Fakerを使ってダミーデータを生成しても良いです。
posts_spec.rbを作成
require 'rails_helper'
RSpec.describe "Posts", type: :request do
before do
@user = FactoryBot.create(:user) #FactoryBotを利用してuserデータを作成
end
describe 'GET #new' do
context "ログインしている場合" do
#サインインする
before do
sign_in @user
end
it '正常にレスポンスが返ってくる' do
get new_post_path
expect(response.status).to eq 200 #正常にレスポンスが返されHTTPステータス200が発生
end
end
context "ログインしていない場合" do
it 'ログインページにリダイレクトされる' do
get new_post_path
expect(response.status).to eq 302 ##リダイレクトされHTTPステータス302が発生
end
end
end
先ほどrails_helperにDeviseをincludeしたのでsign_inというヘルパーが利用でき、ログイン状態を作ることができます。ログインしている場合とログインしていない場合とで、sign_inを使い分けます。
before do
sign_in @user
end
あとはeqマッチャを使って、response.statusを指定します。
#正常にレスポンスが返ってきた場合
expect(response.status).to eq 200
#リダイレクトされた場合
expect(response.status).to eq 302
(レスポンスステータスは https://developer.mozilla.org/ja/docs/Web/HTTP/Status 参照)
これでテストを実行すると、テストが成功するはずです。