2013-02-28 19 views
5

Ben benim modelinde aşağıdaki doğrulayıcı:RSpec testi özel doğrulayıcı

class ContinuumValidator < ActiveModel::Validator 
    def validate(record) 
    if !record.end_time.nil? and record.end_time < record.start_time 
     record.errors[:base] << "An event can not be finished if it did not start yet..." 
    end 
    end 
end 

class Hrm::TimeEvent < ActiveRecord::Base 
    validates_with ContinuumValidator 
end 

nasıl RSpec kullanarak test edebilirsiniz? (zetetic sayesinde)

describe "validation error" do 
    before do 
    @time_event = Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2) 
    end 

    it "should not be valid if end time is lower than start time" do 
    @time_event.should_not be_valid 
    end 

    it "raises an error if end time is lower than start time" do 
    @time_event.errors.should include("An event can not be finished if it did not start yet...") 
    end 
end 

Ama şu hataları alıyorum:: İşte

Ben şimdiye kadar denedim budur

1) Hrm::TimeEvent validation error raises an error if end time is lower than start time 
    Failure/Error: @time_event.errors.should include("An event can not be finished if it did not start yet...") 

    expected #<ActiveModel::Errors:0x007fd1d8e02c50 @base=#<Hrm::TimeEvent id: nil, start_time: "2012-10-05 08:00:00", end_time: "2012-10-05 07:00:00", event_type: 2, employee_id: nil, created_at: nil, updated_at: nil, not_punched: false, validated: false, replace_id: nil>, @messages={}> to include "An event can not be finished if it did not start yet..." 

    Diff: 
    @@ -1,2 +1,5 @@ 
    -["An event can not be finished if it did not start yet..."] 
    +#<ActiveModel::Errors:0x007fd1d8e02c50 
    + @base= 
    + #<Hrm::TimeEvent id: nil, start_time: "2012-10-05 08:00:00", end_time: "2012-10-05 07:00:00", event_type: 2, employee_id: nil, created_at: nil, updated_at: nil, not_punched: false, validated: false, replace_id: nil>, 
    + @messages={}> 

yanlış yapıyorum? Ve hedefime nasıl ulaşabilirim? Herhangi bir yardım veya öneri takdir edilecektir. Teşekkürler.

cevap

11

sorun dize dizisi gibi davranmaya @time_event.errors bekliyorsanız olmasıdır

deneyin. Değil, ActiveModel :: Hatalarını döndürür. Aslında doğrulama test etmedim

it "raises an error if end time is lower than start time" do 
    @time_event.valid? 
    @time_event.errors.full_messages.should include("An event can not be finished if it did not start yet...") 
end 
+0

Haklısın Hatayı almak için full_messages ekleyeceğim. Ancak, diğerinin dediği gibi, doğrulamayı "geçerli" ile test etmem gerekiyor: – siekfried

+0

Doğru. Cevabı güncelledim. –

1

Hatalar tetikleyen bir olayı aramadığınız için hata yok. Bu, bir kayıt oluşturulduğunda veya kaydedildiğinde normal olarak gerçekleşir. Sen olsa testinde veritabanı vurmak istemeyebilirsiniz ve sonra böyle yöntemi valid? kullanabilirsiniz:

it "raises an error if end time is lower than start time" do 
    @time_event.valid? 
    @time_event.errors.should include("An event can not be finished if it did not start yet...") 
end 

Beni şahsen geçerli beri birine bu iki testleri koyar ki? ilk durumda denir. Ayrıca, , if !record.end_time.nil?'dan daha iyidir (Benim düşüncemde en azından .... :-))

+0

Haklısınız, ama @Benjamin Sullivan'ın önerdiği gibi, testlerim için hatalara full_messages eklemem gerekiyor. Ayrıca minnettarlık için de teşekkürler :) – siekfried

0

Bence kayıt onaylanmadı, bu nedenle validatior çalışmadı ve hiçbir hata eklenmedi. Bunu kod çıktısında görebilirsiniz. "Valide: false":

it "raises an error if end time is lower than start time" do 
    @time_event.valid? 
    @time_event.errors.should include("An event can not be finished if it did not start yet...") 
end 
0

artı ben tek spec yapmak öneririm: Diğerleri belirttiği gibi, ayrıca valid? çağrısı ile doğrulamaları tetiklemek gerekiyor.

describe "validation error" do 
    before { @time_event = Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2) } 

    it "raises an error if end time is lower than start time" do 
    @time_event.valid? 
    @time_event.errors.should include("An event can not be finished if it did not start yet...") 
    end 
end 

class ContinuumValidator < ActiveModel::Validator 
    def validate(record) 
    if record.end_time and record.end_time < record.start_time 
     record.error.add_to_base << "An event can not be finished if it did not start yet..." 
    end 
    end 
end 
1

Bu çözüm (Mongoid kullanarak) benim için çalışıyor:

class OpLog 
... 
field :from_status, type: String 
field :to_status, type: String 
... 
validate :states_must_differ 

def states_must_differ 
    if self.from_status == self.to_status 
    errors.add(:from_status, "must differ from 'to_status'") 
    errors.add(:to_status, "must differ from 'from_status'") 
    end 
end 
... 
end 

test modeli:

it 'is expected to have different states' do 
    expect { create(:oplog, from_status: 'created', to_status: 'created').to raise_error(Mongoid::Errors::Validations) } 
end 

Yani sizin durumda ben d Böyle bir test yazınız (eğer ActiveRecord kullanarak):

it 'raises an error if end time is lower than start time' do 
    expect { create(Hrm::TimeEvent.new(start_time: "2012-10-05 10:00:00", end_time: "2012-10-05 09:00:00", event_type: 2)) }.to raise_error(ActiveRecord::Errors) 
end 
İlgili konular