🐥
railsのバリデーションテストでつまずいた話
Railsのバリデーションテストの動作について
Railsのモデルのバリデーションテストは、一般的にshoulda-matchers
というGemを使って書かれることが多いです。しかし、このGemのテストマッチャはどのように動作しているのでしょうか?そして、なぜ予期しないエラーが出ることがあるのでしょうか。この記事では、その背後にある動作をコード例を用いて解説します。
属性のみのバリデーションを実行するマッチャ
validate_presence_of
validate_absence_of
これらのマッチャは、特定の属性に焦点を当てたテストを行います。
# modelの例
class User < ApplicationRecord
validates :name, presence: true
end
# testの例
it { should validate_presence_of(:name) }
このテストはname
をnil
に設定して、その属性のpresence
バリデーションが働くかどうかを確認します。
全体のバリデーションを実行するマッチャ
validate_numericality_of
validate_inclusion_of
validate_exclusion_of
validate_uniqueness_of
これらのマッチャは、特定の属性だけでなく、モデル全体のバリデーションを実行します。
# modelの例
class Product < ApplicationRecord
validates :price, numericality: { greater_than: 0 }
validates :category, presence: true
end
# testの例
it { should validate_numericality_of(:price).is_greater_than(0) }
このテストはprice
を0
や-1
などに設定した後で、全体のバリデーションを実行します。そのため、もしcategory
が正しく設定されていなければ、予期しないエラーが発生することがあります。
予期しないエラーの原因
特定の属性だけを設定して、他の属性を設定しない場合、デフォルト値(通常はnil
)が使用されます。全体のバリデーションを実行するマッチャを使用する場合、他の属性も適切に設定しておく必要があります。
# testの前準備例
before do
subject.category = "Electronics"
end
まとめ
Railsのモデルバリデーションテストを書く際には、どのようなマッチャがどのように動作するのかを理解することが重要です。特に、全体のバリデーションを実行するマッチャを使用する際には、他の属性も適切に設定しておくことをおすすめします。
Discussion