webエンジニアの日常

RubyやPython, JSなど、IT関連の記事を書いています

【Rails】deviseを使うときのログインのテストの書き方

お久しぶりです エンジニアのさもです。

今回は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の書き方やインストールなどは以下のブログなどを参考にして下さい

Rails RSpecの基本 ~導入編~ - Qiita

使える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行ほど追加するだけでしたね。

読者登録をしていただけると、ブログを続ける励みになりますので、よろしくお願いします。