テスト内でのAction Mailer設定をload hookで保護
Rails 8.1では、設定テスト内でのAction Mailerの初期化処理がload hookで適切に保護されるようになりました。これは #56201 で導入されたload hookガードに起因するテストエラーを修正する変更です。
背景
#56201 では、Railsアプリケーションの初期化前にload hookが実行されることを検出する仕組みが導入されました。load hook は本来、Railsアプリケーションが完全に初期化された後に実行されるべきですが、早期に実行されるとバグやパフォーマンスの低下を引き起こします。
新しいガード機構により、ActiveSupport.on_load が適切なタイミング外で呼び出されると警告またはエラーが発生するようになりました。その結果、既存のテストコード内でAction Mailerの設定を直接 ActionMailer::Base に対して行っていた箇所がエラーを引き起こすようになりました。
技術的な変更
railties/test/application/configuration_test.rb 内の smtp_settings 設定テストが修正されました。
変更前:
add_to_config <<-RUBY
ActionMailer::Base.smtp_settings = { domain: "example.com" }
config.load_defaults "7.0"
RUBY
変更後:
add_to_config <<-RUBY
ActiveSupport.on_load(:action_mailer) do
self.smtp_settings = { domain: "example.com" }
end
config.load_defaults "7.0"
RUBY
ActionMailer::Base への直接的な設定を ActiveSupport.on_load(:action_mailer) ブロック内に移動することで、Action Mailerが適切に初期化された後に設定が適用されるようになりました。ブロック内では self が ActionMailer::Base を指すため、self.smtp_settings として設定を行います。
設計判断
load hookガード機構の導入により、Railsの内部テストでも早期初期化を回避する正しいパターンの使用が求められるようになりました。
このテストは config.action_mailer.smtp_settings = nil の場合に ActionMailer::Base.smtp_settings へのフォールバックが機能することを検証しています。直接設定ではなくload hookを使用することで、実際のアプリケーションコードで推奨される書き方とテストコードが一致するようになりました。
load hookガードは開発者に対して「コンポーネントが適切なタイミングで初期化されているか」を意識させる仕組みであり、フレームワーク自体のテストコードがその模範を示す形になっています。
まとめ
本PRは、load hookガード機構の導入に伴って発生したテストエラーを修正する変更です。Action Mailerの設定を ActiveSupport.on_load(:action_mailer) ブロック内に移動することで、コンポーネントの適切な初期化タイミングを保証し、Railsが推奨する初期化パターンをテストコード内でも実践しています。