お久しぶりです エンジニアのさもです。
今回はRailsアプリ内で認証にDeviseというgemを使うwebサービスでログインのテストの書き方をメモしておきます。
スポンサーリンク
経緯
devise自体はgemなので改めてテストする意味はないのですが、今回はdeviseのコントローラ(Devise::SessionsController)を継承したコントローラを実装し、ログイン後にafter_filterで処理をはさむということをやっていました。
テストしたいのはこのログイン後処理です。
ですが、deviseのログインテストは普通にpostでパラメータを送っても通ってくれないです。
「devise ログイン テスト」とかで検索しても「sign_in(user)でログインしたことになるよ~」みたいな記事しか出てこなかったので、メモしておこうと思います。
結果的に、deviseのソースコードを参考にテストを書きました。
以下では、既にrspecを書く準備(rspec-railsやfactory_girl_railsのインストールやinitialize)が済んでいる状況を想定して進めていきます。
rspecの書き方やインストールなどは以下のブログなどを参考にして下さい
使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita <- オススメ
rails_helper.rb
rails_helper.rbのRSpec.configure do ~ endの間に以下を追記します
config.include Devise::Test::ControllerHelpers, type: :controller
バージョンによってはDevise::TestHelpers
と書くみたいなので注意して下さい
私が使っているdeviseのバージョンは4.2.0でした。
テストコード
今回は、customerというモデルがdeviseを使ってログインすることを想定します。userでも同じです
RSpec.describe Customers::SessionsController, type: :controller do describe "会員連携API用テーブルの追加" do subject { <確認したい値> } before do @request.env['devise.mapping'] = Devise.mappings[:customer] @customer = FactoryGirl.create(:customer, password: "password", email: "customer@example.com") end it 'ログイン後処理がうまくいったこと' do post :create, customer: { password: "password", email: "customer@email.com" } expect(controller.customer_signed_in?).to be true expect(controller.current_customer.email).to eq "customer@email.com" is_expected.to eq <想定している値> end end end
before do ~ endの間の1行目がdeviseのテストで必要なコードです。
もしcustomerじゃ無くてuserというモデルをお使いの場合は、@request.env['devise.mapping'] = Devise.mappings[:user]
として下さい。
以上です。
結構悩んだのですが、2行ほど追加するだけでしたね。
読者登録をしていただけると、ブログを続ける励みになりますので、よろしくお願いします。