Factory-girl create that omija walidację mojego modelu

Używam Factory Girl do tworzenia dwóch instancji w moim teście model / jednostka dla grupy. Testuję model, aby sprawdzić, że połączenie do .current zwraca tylko grupy "bieżące" zgodnie z atrybutem expiry, jak poniżej...

  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

Mój problem polega na tym, że mam walidację w modelu, który sprawdza wygaśnięcie nowej grupy po dzisiejszej dacie. Powoduje to błąd walidacji 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 utworzenie grupy lub obejście walidacji, gdy tworzenie za pomocą Factory Girl?

Author: Dave Schweisguth, 2012-02-17

7 answers

Nie jest to bardzo specyficzne dla FactoryGirl, ale zawsze możesz ominąć walidacje podczas zapisywania modeli za pomocą 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
 69
Author: Brandan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-19 15:33:52

Wolę takie rozwiązanie od https://github.com/thoughtbot/factory_girl/issues/578 .

Wewnątrz fabryki:

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

EDIT:

Jak wspomniano w przypisanym wątku i komentarzach/rozwiązaniach innych osób, prawdopodobnie będziesz chciał zawinąć to w blok cech, aby uniknąć nieporozumień/problemów w innych testach; na przykład podczas testowania walidacji.

 49
Author: Jason Denney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-20 17:04:22

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

The nice way, I think:

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)
 15
Author: Tim Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-30 16:49:48

Dla tego konkretnego przypadku walidacji dat-baesd, możesz również użyć gem timecop , aby tymczasowo zmienić czas, aby symulować stary rekord utworzony w przeszłości.

 6
Author: Gabe Martin-Dempesy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-19 21:21:15
foo = build(:foo).tap{ |u| u.save(validate: false) }
 3
Author: Chris Habgood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-08 00:28:15

W zależności od scenariusza można zmienić walidację, aby zdarzyła się tylko przy aktualizacji. Przykład: :validates :expire_date, :presence => true, :on => [:update ]

 1
Author: JoaoHornburg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-28 18:04:09

Twoje fabryki powinny domyślnie tworzyć ważne obiekty. Odkryłem, że atrybuty przejściowe mogą być użyte do dodania logiki warunkowej w następujący sposób:

transient do
  skip_validations false
end

before :create do |instance, evaluator|
  instance.save(validate: false) if evaluator.skip_validations
end

W Twoim teście:

create(:group, skip_validations: true)
 1
Author: acamino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-28 22:14:39