2012-02-17 11 views
49

Używam Factory Girl do utworzenia dwóch instancji w moim modelu/jednostce testowej dla grupy. I 'm testowania modelu, aby sprawdzić, że wezwanie do .aktualnie zwraca tylko grupy „bieżące”, zgodnie z atrybutu ważności, jak na poniżej ...Fabrycznie stworzona dziewczyna pomija moją walidację modelu

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group, :expiry => Time.now + 1.week) } 
    let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 

    specify { Group.current.should == [current_group] } 
    end 

Moim problemem jest to, że mam w modelu walidacji Sprawdzanie, czy nowa grupa wygaśnie po dzisiejszym dniu. Powoduje to niepowodzenie weryfikacji poniżej.

1) Group.current 
    Failure/Error: let!(:expired_group) { FactoryGirl.create(:group, :expiry => Time.now - 3.days) } 
    ActiveRecord::RecordInvalid: 
     Validation failed: Expiry is before todays date 

Czy istnieje sposób na wymuszenie utworzenia grupy lub obejścia sprawdzania poprawności podczas tworzenia przy użyciu Factory Girl?

Odpowiedz

62

To nie jest bardzo specyficzne FactoryGirl, ale zawsze można ominąć podczas zapisywania walidacji modeli poprzez save(:validate => false):

describe ".current" do 
    let!(:current_group) { FactoryGirl.create(:group) } 
    let!(:old_group) { 
    g = FactoryGirl.build(:group, :expiry => Time.now - 3.days) 
    g.save(:validate => false) 
    g 
    } 

    specify { Group.current.should == [current_group] } 
end 
+0

To dokładnie to, czego szukałem, dzięki! – Norto23

+0

Zobacz odpowiedź Jason Denney poniżej na lepsze rozwiązanie. –

5

W tym konkretnym przypadku walidacji data-baesd, można również użyć timecop gem tymczasowo zmienić czas na symulację starego rekordu tworzonego w przeszłości.

1

W zależności od scenariusza można zmienić sprawdzanie poprawności, aby miało to miejsce tylko w przypadku aktualizacji. Przykład: :validates :expire_date, :presence => true, :on => [:update ]

46

Preferuję to rozwiązanie od https://github.com/thoughtbot/factory_girl/issues/578.

Wewnątrz fabryki:

to_create {|instance| instance.save(validate: false) } 
+4

To znacznie bardziej eleganckie rozwiązanie niż zaakceptowane. –

+3

Należy pamiętać, że jeśli zrobiłeś to w swojej fabryce ogólnego przeznaczenia, pomijałbyś walidacje KAŻDEGO czasu, który utworzyłeś w tej fabryce. Najlepiej jest używać tej techniki tylko w pod-fabryce (lub w funkcji). – tgf

+0

Prawie na pewno chcesz wprowadzić to w cechę. Zobacz odpowiedź Tima Scotta poniżej. –

3
foo = build(:foo).tap{ |u| u.save(validate: false) } 
6

To zły pomysł, aby przejść walidację domyślnie w fabryce. Niektóre włosy zostaną wyciągnięte, znajdując to.

Najpiękniejszych sposób, myślę:

trait :skip_validate do 
    to_create {|instance| instance.save(validate: false)} 
end 

Następnie w teście:

create(:group, :skip_validate, expiry: Time.now + 1.week) 
+0

to najlepszy sposób na rozwiązanie tego problemu! –

Powiązane problemy