LoginSignup
8
2

More than 1 year has passed since last update.

devise_token_auth使用時のRspecの認証処理のやり方

Posted at

概要

Railsでdevise_token_authを使用して認証機構を実装しております。
Rspecを利用してテストを書いている際に、テスト内でトークン認証をさせるのに手間取ったので
備忘録としてアウトプットしたいと思います。

方法

ここでは、devise_token_authを使用してトークン認証をしている場合と、
deviseを使用してトークンを使わない認証の場合に分けて記載します。
使用例としてはログインしたユーザーが投稿を作成するというテストを考えていきます。
なおここからは認証のやり方を示すことに重点を置いているためすべて簡易的にコードを記載していきます。

deviseを使用した場合

通常deviseを使用した場合はsign_inというヘルパーメソッドを使用してテスト内でログイン認証を行います。
まず、下記の投稿に関するcontrollerがあるとします。
またコード中に出てくるauthenticated_user!current_usersign_inなどはdeviseを導入すると
使用できるヘルパーメソッドです。
使用方法を詳しく確認したい場合は下記をご確認ください。
devise github

controllers/posts_controller.rb

class PostsController < ApplicationController
  before_action :authenticated_user!, only: [:create]

  def create
    # userモデルとpostモデル間での関連付けはされていると仮定
    current_user.posts.create(params[:post]) #本来はストロングパラメーターを使用してrequestのパラメーターを制限すべきです
  end
end

spec/requests/posts_spec.rb

#省略
describe 'POST /create' do
  let!(:user) { { name: 'example_user', email: 'example@example.com', password: 'passward' } }
  let(:post_params) { { content: 'example_content' } }

  before do
    sign_in user
    post posts_path, params: { post: post_params }
  end

  it 'ステータスコード200が返ってくる' do
    expect(response.status).to eq 200
  end
end
<備考>

下記のようにrails_helper.rbにてヘルパーをincludeするとrequest spec内でsign_inなどのヘルパーが使用できます。

spec/rails_helper.rb

RSpec.configure do |config|
# 省略
  config.include Devise::Test::IntegrationHelpers, type: :request
end

以上でdeviseを使ったログイン認証をする事ができます。

devise_token_authを使用してトークン認証している場合

devise_token_authの基本使用の仕方はdeviseとほぼ同じです。
しかしトークン認証を行っているので、deviseを使用したときのようにただヘルパーメソッドのsign_inを使って
ユーザーをログインさせるだけでは認証ができません。
deviseの場合と同じようにしようとすると、認証エラーで401が返ってきます。

controllers/posts_contorller.rb

class PostsController < ApplicationController
  before_action :authenticated_user!, only: [:create]

  def create
    # userモデルとpostモデル間での関連付けはされていると仮定
    current_user.posts.create(params[:post]) # 本来はストロングパラメーターを使用してrequestのパラメーターを制限すべき
  end
end

deviseのヘルパーメソッドsign_inではトークン認証できないので新たにヘルパーメソッドを作成します。

spec/support/authorization_spec.rb

module AuthorizationHelper
  def sign_in(user)
    post posts_path, params: { email: user.email, password: user.password }
    # レスポンスのHeadersからトークン認証に必要な要素を抜き出して返す処理
    response.headers.slice('client', 'uid', 'token-type', 'access-token')
  end
end

rails_helper.rb

RSpec.configure do |config|
# 省略
  config.include AuthorizationHelper, type: :request
end

spec/requests/posts_spec.rb

#省略
describe 'POST /create' do
  let!(:user) { { name: 'example_user', email: 'example@example.com', password: 'password' } }
  let(:post_params) { { content: 'example_content' } }
    let(:token) { sign_in user } # 追加

  before do
    #sign_in user # 削除
    post posts_path, params: { post: post_params }, headers: token # 追加
  end

  it 'ステータスコード200が返ってくる' do
    expect(response.status).to eq 200
  end
end
<備考>

ヘルパーメソッドを定義する場合はspec配下にsupportディレクトリを作成しその中にファイルを記載します。
そしてrspecがそのファイルを読み込むようにrails_helper.rbで設定を行います。

rails_helper.rb

RSpec.configure do |config|
# 省略
  # デフォルトではコメントアウトされています
  Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
end

以上がdevise_token_authを使用していた場合のrspecにおける認証です。

参考文献

【Rspec・devise token auth】Rails APIアプリのRspecテストでユーザログイン・認証を実装する方法

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