私はこのようなモデルを持っています:
class User < ActiveRecord::Base
validates_length_of :name, :in => (2..5)
end
この検証をテストしたい:
it "should not allow too short name" do
u = User.new(:name => "a")
u.valid?
u.should have(1).error_on(:name)
end
ただし、name
に設定されたエラーの種類はテストされません。 too_short
、too_long
、または他の検証が失敗したかどうかを知りたいです。
次のように、エラー配列でメッセージテキストを検索できます。
u.errors[:name].should include(I18n.t("activerecord.errors.models.user.attributes.name.too_short"))
しかし、モデル固有のメッセージの代わりにロケールファイルにactiverecord.errors.messages.too_short
を設定すると、これは失敗します。
では、どのようなエラーが発生したかを確認することはできますか?
Rails 2011年後半にActiveModelにエラーをクエリするメソッドを追加しました。Rails v3.2 。適切なエラーがあったかどうかを確認してください _#added?
_ :
_# An error added manually
record.errors.add :name, :blank
record.errors.added? :name, :blank # => true
# An error added after validation
record.email = '[email protected]'
record.valid? # => false
record.errors.added? :email, :taken # => true
_
パラメータ化された検証(例:_:greater_than_or_equal_to
_)の場合、パラメータの値も渡す必要があることに注意してください。
_record.errors.add(:age, :greater_than_or_equal_to, count: 1)
record.errors.added?(:age, :greater_than_or_equal_to, count: 1)
_
エラーは、i18nキーによって識別されます。 エラーセクション の下にある任意の言語の適切な Rails i18n ファイルをチェックインするための適切なキーを見つけることができます。
_ActiveModel#Error
_に尋ねることができる他の気の利いた質問には、 _#empty?
_ と #include?(attr)
、および- Enumerable
。
エラーハッシュで翻訳されたエラーメッセージを探すというアイデアは本当に好きではありません。仲間のRubyistsと会話した後、モンキーパッチのエラーハッシュを終了したので、翻訳されていないメッセージが最初に保存されます。
module ActiveModel
class Errors
def error_names
@_error_names ||= { }
end
def add_with_save_names(attribute, message = nil, options = {})
message ||= :invalid
if message.is_a?(Proc)
message = message.call
end
error_names[attribute] ||= []
error_names[attribute] << message
add_without_save_names(attribute, message, options)
end
alias_method_chain :add, :save_names
end
end
次に、次のようにテストできます。
u = User.new(:name => "a")
u.valid?
u.errors.error_names[:name].should include(:too_short)
私が使用するアプローチ:
it "should not allow too short name" do
u = User.new(:name => "a")
expect{u.save!}.to raise_exception(/Name is too short/)
end
例外メッセージには多くの検証メッセージが含まれている可能性があるため、正規表現を使用して例外メッセージを照合しますが、名前が短すぎることに関連する特定のスニペットが含まれていることを確認したいと思います。
このアプローチでは、アサーションを検証メッセージに結合するため、検証メッセージを変更するたびに、仕様も変更する必要があります。ただし、全体として、これは検証が機能していることを表明する簡単な方法です。
これらのタイプの反復検証テストを処理するには、gem shoulda をチェックすることをお勧めします。 RSpecまたはTest :: Unitを補完するため、次のような簡潔な仕様を記述できます。
describe User do
it { should ensure_length_of(:name).is_at_least(2).is_at_most(5) }
end