Factory-girl crée qui contourne la validation de mon modèle

J’utilise Factory Girl pour créer deux instances dans mon test de modèle / unité pour un groupe. Je teste le modèle pour vérifier qu’un appel à .current ne renvoie que les groupes «actuels» conformément à l’atsortingbut d’expiration ci-dessous …

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 

Mon problème est que j’ai la validation dans le modèle qui vérifie l’expiration d’un nouveau groupe est après la date d’aujourd’hui. Cela soulève l’échec de validation ci-dessous.

  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 

Existe-t-il un moyen de créer le groupe avec force ou de contourner la validation lors de la création avec Factory Girl?

Ce n’est pas très spécifique à FactoryGirl, mais vous pouvez toujours contourner les validations lorsque vous enregistrez des modèles via 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 

Je préfère cette solution de https://github.com/thoughtbot/factory_girl/issues/578 .

À l’intérieur de l’usine:

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

MODIFIER:

Comme mentionné dans le thread référencé, ainsi que par les commentaires / solutions des autres, vous voudrez probablement inclure ceci dans un bloc de caractéristiques pour éviter toute confusion / problèmes ailleurs dans vos tests; par exemple, lorsque vous testez vos validations.

Il est déconseillé de sauter les validations par défaut en usine. Certains cheveux seront retirés pour trouver cela.

La plus belle façon, je pense:

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

Alors dans votre test:

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

Pour ce cas spécifique de validation date-baesd, vous pouvez également utiliser le timecop gem pour modifier temporairement l’heure afin de simuler l’ancien enregistrement créé par le passé.

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

Selon votre scénario, vous pouvez modifier la validation pour qu’elle se produise uniquement lors de la mise à jour. Exemple:: :validates :expire_date, :presence => true, :on => [:update ]

Vos usines doivent créer des objects valides par défaut. J’ai trouvé que les atsortingbuts transitoires peuvent être utilisés pour append une logique conditionnelle comme ceci:

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

Dans votre test:

 create(:group, skip_validations: true)