ValidationError がモデルとメッセージを公開するテストを追加
ActiveModel の ValidationError が例外オブジェクトから失敗したモデルとエラーメッセージを取得できることを確認するテストが追加され、例外情報の可視化が保証されました。
背景
ActiveModel::ValidationError はバリデーション失敗時に投げられる例外で、model アクセサとエラーメッセージを生成するロジックを持ちます。従来のテストは例外が発生したかどうかのみを検証し、例外オブジェクトに含まれる情報までは確認されていませんでした。
この欠如は、例外ハンドリングコードやデバッグ時に期待される情報が正しく伝搬されているかを自動的に保証できないというリスクを孕んでいました。validate! が内部で raise_validation_error を呼び出すことは既にテストでカバーされていましたが、#model と #message の具体的な内容は未検証でした。
技術的な変更
activemodel/test/cases/validations_test.rb に test_validate_with_bang_exposes_model_and_message メソッドが新たに追加され、Topic モデルに必須属性 title を設定せずに validate! を実行した際の例外を取得します。
def test_validate_with_bang_exposes_model_and_message
Topic.validates :title, presence: true
topic = Topic.new
error = assert_raise(ActiveModel::ValidationError) do
topic.validate!
end
assert_same topic, error.model
assert_equal "Validation failed: Title can't be blank", error.message
end
テストは assert_raise で例外を捕捉し、assert_same により例外の model が元のインスタンスと同一であること、assert_equal により生成された message が期待文字列と一致することを検証します。これにより例外オブジェクトが正確なコンテキスト情報を保持していることが自動的に保証されます。
設計判断
このテスト追加は、ValidationError が公開すべきインタフェース(model と message)の契約を明示的に検証する方針を反映しています。実装側に変更は不要ですが、テストコードで API の使用例を示すことで、将来的なリファクタリング時に不意の振る舞い変更を防止します。
また、テストだけでカバーできる領域を拡充することにより、開発者は例外情報を利用した高度なエラーハンドリングやロギングを安心して実装できるようになります。これは Rails が提供する 一貫したエラーレポート という設計理念に合致した選択です。
まとめ
テストのみの追加ですが、ActiveModel::ValidationError がモデルとメッセージを正しく公開することを自動検証し、例外情報の信頼性を高めました。これにより開発者は例外オブジェクトを活用したロジックを安全に構築できる基盤が整います。