LoginSignup
4
1

More than 1 year has passed since last update.

RSpecでログイン状態にする方法(sign_inヘルパー)

Posted at

今回のテストを行うアプリの流れ

ログイン
⬇️
目標を決める
⬇️
正常に目標が保存されたら、トップページへ遷移する

RSpecでnewアクション機能の一連の流れをテスト(総合テスト)するにあたり、
ログイン状態にさせてから目的の実装を行うための方法をまとめました。

私自身が初学者のため、同じような方向けの内容となっています。

環境

Ruby 2.6.5
Rails 6.1.3.1

以下インストール済み
Devise 4.8.0
RSpec 3.10.0
FactoryBot
Faker

前提

devise導入後、authenticate_userを使って、
applicationコントローラーのlpアクション以外に非ログイン状態でアクセスすると、
ログイン画面にリダレクトされるようにしています。

application_controller.rb
class ApplicationController < ActionController::Base
  #ログインしていない場合はログイン画面へ強制的に遷移する
  before_action :authenticate_user!, except: [:lp]
  before_action :configure_permitted_parameters, if: :devise_controller?

~中略~

end

テストコード書き方

RSpecでDeviseを使えるようにする

spec/rails_helper.rb
RSpec.configure do |config|

~中略~
  #下のコードを追記
  config.include Devise::Test::IntegrationHelpers, type: :system
end

こちらをrails_helper.rbに記述することで、systemテスト時にdeviseのヘルパーを呼び出すことができます。
※system以外のrequestなどでも同様に使用できます。

テスト用データを用意

FactoryBotを使ってユーザーのテスト用データを用意します。
今回はユーザーデータと目標データの2つが必要なので2つのデータを作りました。

spec/factories/users.rb
FactoryBot.define do
  factory :user do
    nickname              { 'Taro' }
    email                 { Faker::Internet.free_email }
    password              { 'aaBB1234' }
    password_confirmation { password }
    family_name           { '田中' }
    given_name            { '太郎' }
    birth_day             { '1999-01-01' }
  end
end
spec/factories/goals.rb
FactoryBot.define do
  factory :goal do
    saving_goal { '500000' }
    purpose     { '海外旅行を行くため' }
    period      { '2040-01-02' }

    association :user
  end
end

ユーザーモデルにfamily_nameカラムなどを追加している場合は追加したカラムのデータも記述します。
emailカラムはFakerを使ってダミーデータを生成してみました。

総合テスト用ファイルを作る

spec/system/goal_spec.rb
require 'rails_helper'

RSpec.describe 'ゴール新規登録', type: :system do
  before do
  #テスト用データを読み込む
    @goal = FactoryBot.build(:goal)
    @user = FactoryBot.create(:user)
  end

  context '新規登録できること' do
    it '正しい情報を入力すればゴール新規登録ができてトップページに移動する' do
     # 【sign_in @user】 によって、ログイン状態にする
      sign_in @user
      visit new_goal_path
      fill_in 'goal_saving_goal', with: @goal.saving_goal
      select '2022', from: 'goal_period_1i'
      select '12', from: 'goal_period_2i'
      select '12', from: 'goal_period_3i'
      fill_in 'goal_purpose', with: @goal.purpose
      expect do
        find('input[name="commit"]').click
      end.to change { Goal.count }.by(1)
      expect(current_path).to eq(root_path)
    end
 end

先ほどrails_helperにDeviseをincludeしたのでsign_inというヘルパーが利用できます!
sign_inによってログイン状態を作ることができるので、ログインしている場合の総合テストが簡単に実装できるはずです。

最後に

ご覧いただき、ありがとうございます。
私はこの方法で実装できましたが、うまくいかないこともあるかと思います。
sign_inヘルパーを使用しなくとも、before do~end内で行う実装方法も見つけたため、
こちらも残しておきます。参考になれば、嬉しいです。

参考

Rails RSpec コントローラーテストでログイン状態にする

4
1
0

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
4
1