[Rails] ActionView::TestCaseでsetup内で定義した変数が公開されない問題を修正

rails/rails

背景

Rails 8.0以降、ActionView::TestCaseを使用したビューのテストで、setupメソッド内で定義したインスタンス変数がビューに公開されない問題が発生していました。この問題は#56476のリークチェッカー強化により引き起こされていました。

従来、テストケース内で定義したインスタンス変数は自動的にビューコンテキストで利用可能でしたが、after_setupフックでインスタンス変数をキャプチャするタイミングの問題により、setupメソッドで定義した変数が正しく検出されなくなっていました。

問題の詳細

以前の実装では、after_setupメソッドで現在のインスタンス変数をキャプチャしていました:

def after_setup
  @__setup_ivars = instance_variables << :@__setup_ivars
end

しかし、Minitestの実行フローではsetupメソッドがafter_setupに実行されるため、このアプローチではsetup内で定義された変数を正しくキャプチャできていませんでした。

修正内容

今回の修正では、after_setupフックを削除し、代わりにINTERNAL_IVARS定数にリークチェッカーの内部変数を追加することで問題を解決しています:

INTERNAL_IVARS = [
  :@__memoized,
  :@_assertion_wrapped,
  :@_assertions,
  :@_result,
  :@_routes,
  :@controller,
  :@layouts,
  :@locals,
  :@method_name,
  :@output_buffer,
  :@partials,
  :@passed,
  :@rendered,
  :@request,
  :@routes,
  :@tagged_logger,
  :@templates,
  :@updates,
  :@view,
  :@view_context,
  :@view_context_class,
  :@view_flow,
  :@_subscribers,
  :@html_document,
  :@__leak_checker_before_env,  # 新規追加
]

def _user_defined_ivars
  instance_variables - INTERNAL_IVARS  # @__setup_ivarsの参照を削除
end

技術的な意義

この修正により、以下のようなテストコードが正しく動作するようになります:

class MyViewTest < ActionView::TestCase
  def setup
    @user = User.new(name: "Alice")
  end

  test "renders user name" do
    render inline: "<%= @user.name %>"
    assert_select "body", "Alice"
  end
end

_user_defined_ivarsメソッドは、テストケースで定義されたユーザー変数を抽出し、ビューコンテキストに転送する役割を担っています。静的な除外リストを使用することで、テストライフサイクルのどの時点で変数が定義されても、適切に検出・公開できるようになりました。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

ガイドライン準拠 ✓ PASS

記事構成とDiffDaily Styleへの準拠状況

記事構成の3要素(Title, Context, Technical Detail)が明確に記述されています。コードブロック前後の空行やGitHubリンク記法など、カスタムMarkdown構文も正しく使用されており、可読性が非常に高いです。

  • 記事構成(Title、Context、Technical Detail)
  • DiffDaily Styleガイド準拠
  • カスタムMarkdown活用
  • 対象読者への適合性
技術的整合性 ✓ PASS

技術的な正確性と表現の適切性

変更前後のコード引用が的確であり、Diffの内容を正確に反映しています。Minitestのライフサイクルに起因する問題点と、静的な除外リストを用いた解決策についての技術的説明は論理的で正確です。

  • 技術用語の正確性
  • コード例の正確性
  • 説明の技術的正確性
PR内容との整合性 ✓ PASS

元のPR情報との一致度

PRのタイトル、関連Issue/PR番号、そして変更の意図が記事内容と完全に一致しています。PRで提供された情報を超えるような根拠のない主張(ハルシネーション)は見られず、忠実に内容を解説しています。

  • タイトル・説明の一致
  • Diff内容の正確な反映
  • 推測の排除