LoginSignup
2
1

More than 3 years have passed since last update.

rspecでfirebase-auth-railsの認証を通す

Posted at

何をしたか

firebase-auth-railsというgemを使ったプロジェクトを作成したのですが、テストコード(rspec)で認証が通らないため、それを解決した方法を備忘録的に書きました。

事象

例えば下記のようなcontrollerがあったとします。
before_action :authenticate_user で認証が通らないと401エラーになります。

controllers/api/books_controller.rb
class Api::BooksController < Api::ApplicationController
  include Firebase::Auth::Authenticable
  before_action :authenticate_user

  def create
    @book = Book.new(title: params[:title])

    if @book.save
      render json: { book: @book }
    else
      render json: { error: @book.errors.messages }, status: :internal_server_error
    end
  end
end

このcontrollerのテストコードを書いてみます。
headerのAuthorizationには適当な値を入れています。
今回はAuthorizationの値は任意で問題ない想定です。

require 'rails_helper'

RSpec.describe Api::BooksController, type: :request do
  describe '#create' do
    let (:headers) {
      {
        'Content-Type': 'application/json',
        Authorization: "Bearer token"
      }
    }

    it 'return 200' do
      post api_books_path, params: { title: 'タイトル' }.to_json, headers: headers
      expect(response).to have_http_status 200
    end
  end
end

上記のテストコードはテストが通りません。
before_action :authenticate_user で認証が通らないためです。
そのため上記のテストコードでテストが通るように諸々追加します。

解決方法

spec/support配下にfirebase_stub.rbを作成
Firebase::Auth::Authenticableauthenticate_entityというメソッドが引数で指定したuserを返すようなstubを作成します。
Firebase::Auth::Authenticable

spec/support/firebase_stub.rb
module FirebaseStub
  def stub_firebase(user)
    allow_any_instance_of(Firebase::Auth::Authenticable).to receive(:authenticate_entity).and_return(user)
  end
end

spec/rails_helper.rbFirebaseStubを追加

spec/rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'

# ...略

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

# ...略

RSpec.configure do |config|

# ...略

  config.include FirebaseStub
end

最後に先ほどのテストコードにstub_firebaseをbeforeで実行するよう追加します。
userはここではFactoryBotで予め定義されている前提で書きました。

require 'rails_helper'

RSpec.describe Api::BooksController, type: :request do
  describe '#create' do
    let (:headers) {
      {
        'Content-Type': 'application/json',
        Authorization: "Bearer token"
      }
    }
+   let(:user) { FactoryBot.create(:user) }

+   before { stub_firebase(user) }

    it 'return 200' do
      post api_books_path, params: { title: 'タイトル' }.to_json, headers: headers
      expect(response).to have_http_status 200
    end
  end
end

以上の設定によってテストコードで認証が通るかと思います。
また、current_userを使うと、stub_firebaseの引数のuserが取得できます。

今回はtokenの値を一切使わなかったため、もっといい書き方があるかと思いますが、自分はこう解決しました。

firebase-auth-rails

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