💎

【Ruby】永続的セッションテストのエラー解決方法

2024/05/25に公開

はじめに

こんにちは、Takeです。都内の自社開発企業でエンジニアとして働いています。

この記事では、Rails Tutorial 第7版の第9章 「リスト 9.33: 永続的セッションのテスト」で遭遇したエラーとその解決方法を共有します。

https://railstutorial.jp/chapters/advanced_login?version=7.0#sec-remember_tests

前提

以下のコードでは、例外を発生させる raise メソッドをすでに外した状態でテストを走らせています。

app/helpers/sessions_helper.rb

module SessionsHelper
  .
  .
  .
  # 記憶トークンcookieに対応するユーザーを返す
  def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.encrypted[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end
  .
  .
  .
end

エラーメッセージ

test/helpers/sessions_helper_test.rbのテストを実行後にエラーを確認

$ rails test test/helpers/sessions_helper_test.rb
Started with run options --seed 18943

 FAIL SessionsHelperTest#test_current_user_returns_right_user_when_session_is_nil (0.05s)
        --- expected
        +++ actual
        @@ -1 +1 @@
        -#<User id: 762146111, name: "Michael Example", email: "michael@example.com", created_at: "2024-05-25 03:22:25.088892000 +0000", updated_at: "2024-05-25 03:22:25.127910000 +0000", password_digest: [FILTERED], remember_digest: "$2a$04$rJEdjWwj/WdjTrZuQl8iEO7JSUknnkt2BZrv7BjM97e...">
        +nil
        test/helpers/sessions_helper_test.rb:11:in `block in <class:SessionsHelperTest>'

  2/2: [=========================================================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.06056s
2 tests, 2 assertions, 1 failures, 0 errors, 0 skips

以下の部分が条件を満たせていないよ」と言われている

  • test/helpers/sessions_helper_test.rb:11:in block in <class:SessionsHelperTest>

該当コード

test/helpers/sessions_helper_test.rb:11:in block in <class:SessionsHelperTest> ってどこのこと?

require "test_helper"

class SessionsHelperTest < ActionView::TestCase

  def setup
    @user = users(:michael)
    remember(@user)
  end

  test "current_user returns right user when session is nil" do
    assert_equal @user, current_user   # <------------------ こちら
    assert is_logged_in?
  end

  test "current_user returns nil when remember digest is wrong" do
    @user.update_attribute(:remember_digest, User.digest(User.new_token))
    assert_nil current_user
  end
end

結論(エラー解消)

以下のようにtest/helpers/sessions_helper_test.rbを修正することでエラーを解消できました。

  test "current_user returns right user when session is nil" do
    log_in_as @user  # <------------------- 追加
    assert_equal @user, current_user
    assert logged_in?
  end

log_in_as @user を使うことで、テスト用のユーザーをログインさせてセッションに保持することができます。これにより、current_user が正しくユーザーを返すようになって期待通りにテストが成功ししたと考えられます。

https://stackoverflow.com/questions/31763060/failure-sessionshelpertesttest-current-user-returns-right-user-when-session-i

log_inlog_in_as

注意

結論

(私の場合はどちらかといえば...)log_in_as を使用します。

理由

log_in_as はテスト用のメソッドであり、テストのセットアップを簡単に行うことができると考えているためです。

log_inlog_in_asの違い

log_in_as @user:

  • テスト用のヘルパーメソッドであり、ユーザーをログイン状態にするためのもの。
  • このメソッドはテスト環境で使用されることが多く、テスト用にカスタマイズされた挙動を保持するため。
module TestHelper
  # テストユーザーとしてログインする
  def log_in_as(user)
    session[:user_id] = user.id
  end
end

log_in @user:

  • これは実際のアプリケーションコードでユーザーをログインさせるためのメソッド。
  • 標準的なセッション管理の過程を経て、実際のログインプロセスを再現。
module SessionsHelper
  # ユーザーをログインさせる
  def log_in(user)
    session[:user_id] = user.id
  end
end

まとめ

この記事ではRailsの永続的セッションのテストで発生したエラーを解消する方法を紹介しました。主にテスト用として使用されるlog_in_asメソッドを用いることでテストが期待通りに動作するようになりました。皆さんの開発に役立てば幸いです。

最後に

ここまで読んでいただきありがとうございました!
今回の記事が良かったと思ったらぜひ「いいね」を押していただけると嬉しいです 🎉

noteでも記事を執筆していますので、ぜひチェックしてみてください。
https://note.com/take_lifelog/n/n58df7ce7af6f

他にもこのようなことについて記載しているのでお読みいただければ幸いです。

https://zenn.dev/take_tech/articles/275e5f4242973d

https://zenn.dev/take_tech/articles/374817f256ec9d

最後までお読みいただき、誠にありがとうございました!

Discussion