ミニテストでポストリクエスト後に Current.user が nil に設定される
概要
現在の属性を使用しています。 https://translate.google.com/translate?hl=ja&sl=en&tl=ja&u=https://api.rubyonrails.org/classes/ActiveSupport/CurrentAttributes.html
class Current < ActiveSupport::CurrentAttributes
attribute :account, :user
attribute :request_id, :user_agent, :ip_address
resets { Time.zone = nil }
def user=(user)
super
self.account = user.account
Time.zone = user.time_zone
end
end
Minitest を使用してポストリクエストを行うと、Current が空のハッシュに設定されます。取得リクエストは問題ありません。これはバックグラウンド ジョブで発生するはずであることがわかりました: https://github.com/rails/rails/issues/36298 - 最後の投稿のハックは機能しますが、他のオプションがあるかどうかを調べたいと思います。
しかし、投稿リクエストでなぜそれが起こるのかわかりません。
テスト例:
test "create new contact" do
Current.user = users(:standard_user)
new_contact_params = {contact: {first_name: "first name", last_name: "last name"}}
post contacts_path, params: new_contact_params
Current.user # Current user is nil here so I can't do something like Current.user.contacts.any?
assert_response :success
end
解決策
テストで Current.user が nil である理由は、Minitest がメイン アプリケーション スレッドとは別のスレッドで実行されるためです。投稿リクエストを行うと、リクエストはメイン アプリケーション スレッドによって処理されますが、CurrentAttributes オブジェクトは別のスレッドでは使用できません。
これを修正するには、Minitest の around フックを使用して、メイン アプリケーション スレッドでリクエストを実行します。以下に例を示します。
class CreateContactTest < ActiveSupport::TestCase
test "create new contact" do
Current.user = users(:standard_user)
around do |example|
in_main_thread do
example.run
end
end
new_contact_params = {contact: {first_name: "first name", last_name: "last name"}}
post contacts_path, params: new_contact_params
assert_response :success
assert Current.user.contacts.any?
end
end