シュッと開発日記

学んだことのアウトプット。ポートフォリオ作ってます。

OmniAuthでのログインをテストする

OmniAuthとdeviseを使ってTwitterGoogleのログイン機能を実装しましたが、 ログインのテストができずにいたので、今回system specの実装をしてみました。

準備

テストモードを有効にする

まずOmniAuthのテストモードを有効にする為に、

OmniAuth.config.test_mode = true

rails_helper.rbに記載しました。

こうすることで、テスト時にOmniAuthと実際に通信することが無くなります。

モックを作成する

OmniAuth.config.mock_authを使うことで、テスト時にOmniAuthでログインしようとすると ここで作られたモックを返すことができます。

# spec/support/omniauth_helpers.rb

module OmniAuthHelpers
  def set_omniauth(service = :twitter)
    OmniAuth.config.test_mode = true

    OmniAuth.config.mock_auth[service] = OmniAuth::AuthHash.new({
      provider: service.to_s,
      uid: '1234',
      info: {
        name: 'mockuser',
        image: "https://test.com/test.png"
      }
      })
  end
end

モックを実装したヘルパーを呼び出す

このモジュールをrails_helperincludeすることで、 先ほどのモックがスペックの中で実際に使えるようになります。

# spec/rails_helper.rb

OmniAuth.config.test_mode = true
  config.include OmniAuthHelpers

テストの実装

あとは実際のテストの実装になります。

# spec/system/omniauth_users_spec.rb

require 'rails_helper'

RSpec.describe "Users through OmniAuth", type: :system do

  describe "OmniAuthのログイン" do
    context "twitterでのログイン" do

      before do
        OmniAuth.config.mock_auth[:twitter] = nil
        Rails.application.env_config['omniauth.auth'] = set_omniauth
        visit root_path
      end

      it "ログインをするとユーザー数が増える", js: true do
        expect {
          click_link 'Twitterでログイン'
        }.to change(User, :count).by(1)
        expect(page).to have_content 'プロフィール設定'
        expect(page).to have_content 'Twitter アカウントによる認証に成功しました'
      end
    end

    context "googleでのログイン" do

      before do
        OmniAuth.config.mock_auth[:google] = nil
        Rails.application.env_config['omniauth.auth'] = set_omniauth :google
        visit root_path
      end

      it "ログインをするとユーザー数が増える", js: true do
        expect {
          click_link 'Googleでログイン'
        }.to change(User, :count).by(1)
        expect(page).to have_content 'プロフィール設定'
        expect(page).to have_content 'Google アカウントによる認証に成功しました'
      end
    end
  end
end

今回は以上です。

参考