Techioz Blog

Rspec で ActiveRecord::NotNullViolation をキャッチするにはどうすればよいですか?

概要

次の Rspec があります。

before { model.update(calendar_id: nil) }
...
expect { job.perform_now(item_id) }.to raise_error(ActiveRecord::NotNullViolation)

これは失敗し、次のエラー メッセージが表示されます。

何が起こるかというと、ジョブはモデルを更新し (モデルには非 null 制約がありません)、calendar_id を NULL に設定しますが、次のコードを含むコールバックも呼び出します。

another_model.update_all(calendar_id: calendar_id)

another_model には非 null 制約セットがあります。したがって、calendar_is が NULL であるため、update_all ステートメントは失敗しますが、これは問題ありません。しかし、なぜ Rspec はエラーをキャッチしないのでしょうか?

解決策

問題は、expect ブロック内ではなく、before 内でエラーが発生することです。したがって、expect 内の前からロジックを移動すると、問題が解決されます。

expect do
  model.update(calendar_id: nil)
  job.perform_now(item_id) // not even needed
end.to raise_error(ActiveRecord::NotNullViolation)