LoginSignup
10
9

More than 3 years have passed since last update.

Rails チュートリアル(8章)をRSpecでテスト

Posted at

はじめに

以前書いた記事です!

Rails チュートリアル(3章、4章、5章)をRSpecでテスト
Rails チュートリアル(6章)をRSpecでテスト
Rails チュートリアル(7章)をRSpecでテスト

テストを書く(8章)

Sessionsのフラッシュメッセージのテスト(ログイン失敗)

元のテスト↓
8.1.5 フラッシュのテスト -Ruby on Rails チュートリアル

spec/systems/sessions_spec.rb

require 'rails_helper'

RSpec.describe 'Sessions', type: :system do
  before do
    visit login_path
  end
  #無効な値を入力する
  describe 'enter an invalid values' do
    before do
      fill_in 'Email', with: ''
      fill_in 'Password', with: ''
      click_button 'Log in'
    end
    subject { page }
    #フラッシュメッセージが出る
    it 'gets an flash messages' do
      is_expected.to have_selector('.alert-danger', text: 'Invalid email/password combination')
      is_expected.to have_current_path login_path
    end
    #違うページにアクセスしたとき
    context 'access to other page' do
      before { visit root_path }
      #フラッシュメッセージが消える
      it 'is flash disappear' do
        is_expected.to_not have_selector('.alert-danger', text: 'Invalid email/password combination')
      end
    end
  end
end

ログインのテスト(ログイン成功)

spec/systems/sessions_spec.rb

RSpec.describe 'Sessions', type: :system do
  before do
    visit login_path
  end

  describe 'enter an valid values' do
    let!(:user) { create(:user, email: 'loginuser@example.com', password: 'password') }
    before do
      fill_in 'Email', with: 'loginuser@example.com'
      fill_in 'Password', with: 'password'
      click_button 'Log in'
    end
    subject { page }
    #ログインしたときのページのレイアウトの確認
    it 'log in' do
      is_expected.to have_current_path user_path(user) #現在のページのurlについて検証
      is_expected.to_not have_link nil, href: login_path
      click_link 'Account' #ドロップダウンリンクをクリック
      is_expected.to have_link 'Profile', href: user_path(user)
      is_expected.to have_link 'Log out', href: logout_path
    end
  end

#ここから下は以前書いた分-------------------------------------------------------------
  describe 'enter an invalid values' do
    before do
      fill_in 'Email', with: ''
      fill_in 'Password', with: ''
      click_button 'Log in'
    end
    subject { page }
    it 'gets an flash messages' do
      is_expected.to have_selector('.alert-danger', text: 'Invalid email/password combination')
      is_expected.to have_current_path login_path
    end
    context 'access to other page' do
      before { visit root_path }
      it 'is flash disappear' do
        is_expected.to_not have_selector('.alert-danger', text: 'Invalid email/password combination')
      end
    end
  end
end

次にRequest Specで有効な値でログインしたときにセッションに値が入っているかテストします。
そのためにis_logged_in?という論理値を返すテスト用のヘルパーメソッドをつくります。

Helperの作成

まず、ヘルパーを使うための設定

spec/rails_helper.rb

#コメントアウトになっているので解除、なければ追加する
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }

RSpec.configure do |config|
  config.include TestHelper #作成したヘルパーを追加
end

specフォルダーにsupportフォルダーをつくり、その中にヘルパーファイルを追加します。

spec/support/test_helper.rb

module TestHelper
  def is_logged_in?
    !session[:user_id].nil?
  end
end

これでテストでis_logged_in?が使えます。

ログインのテスト(ログイン成功)

spec/requests/access_to_sessions_spec.rb

require 'rails_helper'

RSpec.describe 'access to sessions', type: :request do
  let!(:user) { create(:user) }
  describe 'POST #create' do
    it 'log in and redirect to detail page' do
      post login_path, params: { session: { email: user.email,
                                            password: user.password } }
      expect(response).to redirect_to user_path(user)
      expect(is_logged_in?).to be_truthy #ログインしているかのテストここでis_logged_in?を使ってます。
    end
  end
end

ユーザー作成時にログインしているかのテスト

spec/requests/access_to_users_spec.rb

# ほとんど以前書いていた分です。
describe 'POST #create' do
    context 'valid request' do
      it 'adds a user' do
        expect do
          post signup_path, params: { user: attributes_for(:user) }
        end.to change(User, :count).by(1)
      end

      context 'adds a user' do
        before { post signup_path, params: { user: attributes_for(:user) } }
        subject { response }

        it { is_expected.to redirect_to user_path(User.last) }
        it { is_expected.to have_http_status 302 }
        #ここから追加----------------------------------------------------------
        it 'log in' do
          expect(is_logged_in?).to be_truthy
        end
        #ここまで-------------------------------------------------------------
      end
    end
  end

ログアウトのテスト

sessions_spec.rbにログアウトのテストを追記します。

spec/systems/sessions_spec.rb

require 'rails_helper'

RSpec.describe 'Sessions', type: :system do
  before do
    visit login_path
  end

  describe 'enter an valid values' do
    let!(:user) { create(:user, email: 'loginuser@example.com', password: 'password') }
    before do
      fill_in 'Email', with: 'loginuser@example.com'
      fill_in 'Password', with: 'password'
      click_button 'Log in'
    end
    subject { page }
    it 'log in' do
      is_expected.to have_current_path user_path(user)
      is_expected.to_not have_link nil, href: login_path
      click_link 'Account'
      is_expected.to have_link 'Profile', href: user_path(user)
      is_expected.to have_link 'Log out', href: logout_path
    end
    #追記したログアウトのテストです。-----------------------------------------------
    it 'log out after log in' do
      click_link 'Account'
      click_link 'Log out'
      is_expected.to have_current_path root_path
      is_expected.to have_link 'Log in', href: login_path
      is_expected.to_not have_link 'Account'
      is_expected.to_not have_link nil, href: logout_path
      is_expected.to_not have_link nil, href: user_path(user)
    end
    #ここまで----------------------------------------------------------------
  end

  describe 'enter an invalid values' do
    before do
      fill_in 'Email', with: ''
      fill_in 'Password', with: ''
      click_button 'Log in'
    end
    subject { page }
    it 'gets an flash messages' do
      is_expected.to have_selector('.alert-danger', text: 'Invalid email/password combination')
      is_expected.to have_current_path login_path
    end
    context 'access to other page' do
      before { visit root_path }
      it 'is flash disappear' do
        is_expected.to_not have_selector('.alert-danger', text: 'Invalid email/password combination')
      end
    end
  end
end

Request Specでログアウトしたときにセッションがnilになっているかテストします。

spec/requests/access_to_sessions_spec.rb

describe 'DELETE #destroy' do
  it 'log out and redirect to root page' do
    delete logout_path
    expect(response).to redirect_to root_path
    expect(is_logged_in?).to be_falsey #ここでセッションの値をテストしています。
  end
end

これで8章のテストがおわりです。

10
9
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
10
9