概要

Ruby on Rails(以下Rails)では、ユーザーのログインなどをdeviseというgemを使うことで、簡単に実装することができます。

しかし、ユーザーのログイン機能などを実装すると、テストを記述する際にログインした状態、していない状態などを指定してテストをするということになります。

そのようなdeviseを用いたテストの書き方をここでは説明します。

環境

  • Ruby on Rails 7.0.0
  • devise 4.8.1
  • Minitest

やること

ログインに関連した処理として、ここでは次のものを記述します。

  • fixtureの記述
  • Controllerテスト、Integrationテストの記述

ひとつめは、devise特有のデータ構造のためのデータの記述方法についてです。ふたつめは、テスト時のログイン、ログアウトなどの記述方法などを説明します。

fixtureの記述

fixtureは、テストで利用するデータベースに入れるデータを記述するファイルです。

deviseを利用してモデルを作成すると、devise特有の項目などがあり、メールアドレスやパスワードをそのまま設定するだけでは、うまくいかないということがあります。

今回は、Userという名前のモデルに対して、データを記入する方法を次に紹介します。Userというモデルであるので、fixtureのファイル名はusers.ymlです。User以外のモデルの場合は、それぞれのモデルにあった、fixtureのファイルを利用してください。

alice:
  email: "[email protected]"
  encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
  confirmed_at: <%= Time.now - 100 %>

bob:
  email: "[email protected]"
  encrypted_password: <%= Devise::Encryptor.digest(User, 'password') %>
  confirmed_at: <%= Time.now - 100 %>

重要な部分は、encrypt_passwordに、deviseの提供するメソッドを利用して、パスワードを作成しているということです。

confirmed_atは、deviseの利用時にメールによる認証を追加した場合に、認証を終えたことを示すためのものです。メールによる認証をしていない場合は、これはいりません。しかし、メールによる認証をしている場合は、この記述がないと、次のテストの記述の時にサインインができないという症状に遭遇してしまいます。

これで、テスト前の準備は整いました。

テストの記述

次に、テストを記述していきます。

deviseが関係する、サインインをしたりサインアウトをしたりする処理は、コントローラーや統合テストで行います。

基本的には、deviseが提供するテスト用の機能を利用することでこれらのことを実現します。

早速、コードについて見ていきます。コントローラーテストでも、統合テストでも、記述は同じです。

require 'test_helper'

class TestControllerTest < ActionDispatch::IntegrationTest
  # deviseのテスト用メソッドをインクルード
  include Devise::Test::IntegrationHelpers

  def setup
    @user = users(:alice)
    # サインインするとき
    sign_in(@user)
    # サインアウトするとき
    sign_out
  end

  # ここに適当なテストを記述します
end

こちらの記述は、setupの中でサインインとサインアウトの両方をしているため、意味はあまりないものです。テストの際には、サインインだけをしたり、サインアウトをそれぞれのテストメソッドの方に記述して、それによる動作の変化をテストするなどした方が良いです。

それぞれのコードを見ると、それほど難しいものはなく、includeでdeviseのテスト用のメソッドを読み込み、sign_inやsign_outでサインインやサインアウトを実現しています。

sign_inでは、fixtureで作成したUserモデルのインスタンスをusres(:alice)のような形で用意して、引数に与えています。これで、サインインするユーザーを操作できます。

ちなみに、記事を書く過程で調べたのですが、includeしたファイルにはsign_inとsign_outメソッドしか公開されているメソッドはありませんでした。

こうすることで、deviseを利用したアプリケーションでテストが書きやすくなりました。

さいごに

ユーザー認証は、一から作ろうとするととても大変なので、私はよくdeviseを利用しています。最初は覚えることが多いですが慣れてしまえば、色々と準備がされているためとても快適につかうことができます。

deviseを利用したテストの書き方の参考にしてみてください。