14
3

assert_raise(ActiveRecord::RecordNotFound)で沼った件

Last updated at Posted at 2024-06-27

きっかけ

ActiveRecord::RecordNotFoundを発生させるテストケースがなぜか失敗し、沼ってしまいました。
原因がわからなくて気持ち悪かったので色々と調査してみました。

やりたいテスト

以下のように、staffsテーブルから対象のstaff_idを持つレコードを取得するアクションを考えます。
findメソッドを使用しているため、テーブルにレコードが存在しない場合はActiveRecord::RecordNotFoundが発生します。

class ProfilesController

    # get profiles_show_path(:person_id)で実行されるアクション
    def show
        @staff = Staff.find(params[:person_id])
    end
    
end

この時、例外が発生していることをテストするケースを考えます。
assert_raiseを使用して以下のように書いてみました。

test '対象のstaffレコードが取得できない場合に例外が発生する' do
    assert_raise(ActiveRecord::RecordNotFound) do
        # staff_id = 100のレコードは存在しないため例外が発生する
        get profiles_show_path(100)
    end
end

期待通りActiveRecord::RecordNotFoundが発生した場合にこのテストはパスします。
ですが...

# => Minitest::Assertion: ActiveRecord::RecordNotFound expected but nothing was raised.

は?例外発生してないんだが...

私の心の中

findってレコード取得できない時に例外発生すると思ってたんだけど違ったっけ」
→ あってます。新人の頃200回くらいググりましたよね。

「どこかにrescue処理書いたっけ、探してみよう」
→ 見つかりません。だって書いてないもん。

もうパニックです。

犯人

この挙動が理解できず、色々と調べていくうちに犯人がわかりました。

test環境のconfigファイルを見てみる

config/environments/test.rbの中に以下のような記述があります。

# Render exception templates for rescuable exceptions and raise for other exceptions.
  config.action_dispatch.show_exceptions = :rescuable

こいつの説明はRailsガイドにありました。

config.action_dispatch.show_exceptions設定は、リクエストへの応答中に発生した例外をAction Packで処理する方法を制御します。

:rescuable: config.action_dispatch.rescue_responsesで宣言されている例外についてはHTMLエラーページを表示する

Rails 7.1以降で生成したアプリケーションのconfig/environments/test.rbには config.action_dispatch.show_exceptions = :rescuableが設定されます。

なんと、テスト環境では発生したActiveRecord::RecordNotFoundがレスキューされ、404ページをレンダーするように処理されていたのです...

テストを書き直す

以上を踏まえて以下のようにテストを書き直しました。

test '対象のstaffレコードが取得できない場合に例外が発生する' do
    get profiles_show_path(100)
    assert_response(404)
end

補足

config.action_dispatch.show_exceptions = :rescuableがデフォルト設定されるのはRails7.1以降です。:rescuable以外には:all:noneが選択肢としてあります。

それ以前のバージョンではtruefalseが選択肢だったようです。
しかもconfig.action_dispatch.show_exceptions = falseがデフォルト設定されているので普通に例外発生します。知らんかった...

最後に

この記事が私みたいに沼る人を救えるよう願います。

参考

14
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
3