2011-09-14 26 views
29

kullanarak Rails'e dahil etme geçerliliği ActiveRecord'umda aşağıdaki doğrulama var.Sınama işlemini nasıl test edebilirim: RSpec

validates :active, :inclusion => {:in => ['Y', 'N']} 

Model doğrulamalarımı test etmek için aşağıdakileri kullanıyorum.

should_not allow_value('A').for(:active) 
should allow_value('Y').for(:active) 
should allow_value('N').for(:active) 

Bunu sınamak için daha temiz ve daha fazlası var mı? Şu anda RSpec2 ve shoulda maççıları kullanıyorum.

DÜZENLEME Sadece bu test etmenin bu muhtemelen 'Tamam' bir yolu, olmalıydı bunun için kendi özel eşleyici yazabilir gerektirir bunun için bir şey ve herkes sağlamaz bulundu etrafa bazı sonra

(Ve muhtemelen projeye geri katkıda bulunur). Yukarıda işaret

  • Linkler: intresting olabilir tartışmalara bazı bağlantılar. Link 1, Link 2

  • should_ensure_value_in_range Bu seferki kullanılabilir ne yakın geliyor, ama sadece aralıkları ve değerler listesi kabul eder. Özel eşleştirici buna dayanabilir.

    Örnekler:

    it { should validate_inclusion_check_constraint_on :status, :allowed_values => %w(Open Resolved Closed) } 
    it { should validate_inclusion_check_constraint_on :age, :allowed_values => 0..100 } 
    

    eşleştirici

cevap

53

Kullanım shoulda_matchers en az v2.7 olarak shoulda-matchers son sürümlerinde (In

.0), yapabilirsiniz:

expect(subject).to validate_inclusion_of(:active).in_array(%w[Y N]) 

Bu doğrulama olarak kabul edilebilir bir değerler dizisi tam olarak bu spec eşleştiğini test eder. Önceki versiyonlarda

,> = v1.4, shoulda_matchers bu sözdizimini destekler:

it {should ensure_inclusion_of(:active).in_array(%w[Y N]) } 
+0

Diğer değerleri göz ardı etmediğini kontrol etmek için , aşağıdaki gibi bir şey yapabilirsiniz: 'it {should_not allow_value ('? '). For (: active)} '- dediğiniz gibi, tüm olası değerleri denetleyemezsiniz, ancak Bu izin verilen tüm değerleri kontrol ek olarak makul kapsama gibi görünüyor. – bjnord

+0

** 'e atıfta bulunduğunuz shoulda_matcher **, orijinal olarak belirttiğiniz gibi çalışır, yani sağlanan dizide olmayan değerlere izin vermez. [Belgelere bakın] (https://github.com/thoughtbot/shoulda-matchers#ensure_inclusion_of). İyi bir ölçüm için bunu Rails uygulamasında test ettim ve doğru bir şekilde çalışıyor. –

+1

@LarsLevie - Yorum için teşekkürler. 'Disallows_value_outside_of_array?' Seçeneğini kontrol etmek için doğrulama işlemini değiştirmiş görünüyor. Şu andaki https://github.com/thoughtbot/shoulda-matchers/blob/v1.2.0/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb#L86 adresine bakın ve şimdi https://github.com/thoughtbot/shoulda- eşleştiriciler/blob/15abdf066732828034efea751c2937aa81d080fe/lib/shoulda/matchers/active_model/warranty_inclusion_of_matcher.rb # L90 –

1

Böyle bir şey sınamak yakın geliyor dener (üzerinde çalıştığım projelerden birinde) bir özel gerekirdi eşleyici bulundu onu kurtarmaya çalıştığında patlayan bir DB kısıtlaması olduğundan emin olmaya çalışır. Fikrin özünü vermeye çalışacağım. Kibritler? uygulama gibi bir şey yapar:

begin 
    @allowed_values.each do |value| 
     @subject.send("#{@attribute}=", value) 
     @subject.save(:validate => false) 
    end 
    rescue ::ActiveRecord::StatementInvalid => e 
    # Returns false if the exception message contains a string matching the error throw by SQL db 
    end 

biz biraz @subject.save söylemek ve istisna dize yakın gerçek durum hata iletisi ile eşleşen bir şey içerdiğinde Raylar doğrulama patlatmak, biz yanlış dönebilirsiniz izin yukarıda değiştirirseniz sanırım.

Bunun projeye geri dönüş için mükemmel olmaktan çok uzak olduğunu biliyorum, ancak gerçekten çok fazla :inclusion doğrulamasını test etmek istiyorsanız, projenize özel bir eşleyici olarak eklemek kötü bir fikir olmayabilir.

+0

ben başka bir şey bulamıyorum çünkü burada kendi cevabı kabul, ama nasıl eleştirmek çekinmeyin olacak Yukarıdaki çözüm başarısız olabilir veya bunu yapmak bile zahmetli bir fikirse. – jake

23

Boolean Y/N'den daha fazla sınama yapacak öğeleriniz varsa, bunu da deneyebilirsiniz. sadece sabit değerler izin verildiğini testler böylece

it "should allow valid values" do 
    %w(item1 item2 item3 item4).each do |v| 
    should allow_value(v).for(:field) 
    end 
end 
it { should_not allow_value("other").for(:role) } 

Ayrıca size modelinde tanımladığınız sabit olan %w() yerini alabilir.

CONSTANT = %w[item1 item2 item3 item4] 
validates :field, :inclusion => CONSTANT 

Ardından testi:

it "should allow valid values" do 
    Model::CONSTANT.each do |v| 
    should allow_value(v).for(:field) 
    end 
end 
İlgili konular