Domanda

Sto usando Factory Girl per creare due istanze nel mio test di modello / unità per un gruppo. Sto testando il modello di verificare che una chiamata a rendimenti .Current solo i gruppi 'corrente' in base all'attributo di scadenza di cui al di sotto ...

  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

Il mio problema è che ho la validazione del modello che i controlli di scadenza di un nuovo gruppo è dopo la data di oggi. Ciò solleva l'errore di convalida di seguito.

  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

C'è un modo per forza creare il gruppo o aggirare la convalida durante la creazione utilizzando Factory Girl?

È stato utile?

Soluzione

Questo non è molto specifico per factorygirl, ma si può sempre bypass convalide durante il salvataggio di modelli tramite 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

Altri suggerimenti

Io preferisco questa soluzione da https://github.com/thoughtbot/factory_girl/issues/578 .

All'interno della fabbrica:

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

Modifica

Come accennato nel thread di riferimento, e da altri di commenti / soluzioni, è probabile che vuole avvolgere questo in un blocco di carattere per evitare confusione / problemi in altre parti i test; per esempio, quando si sta testando le vostre convalide.

E 'una cattiva idea di saltare le convalide per impostazione predefinita in fabbrica. Alcuni capelli sarà tirato fuori trovando che.

Il modo più bello, penso:

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

Poi nel test:

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

Per questo specifico caso la convalida della data-baesd, si potrebbe anche utilizzare il Timecop gioiello in tanto temporaneamente alter per simulare il vecchio record di essere creato in passato.

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

I tuoi fabbriche dovrebbero creare oggetti validi per impostazione predefinita. Ho scoperto che transitoria attributi può essere utilizzato per aggiungere logica condizionale in questo modo:

transient do
  skip_validations false
end

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

Nel test:

create(:group, skip_validations: true)

Non è meglio saltare tutta la convalida di quel modello.

creare il file spec/factories/traits.rb.

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

fix spec

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

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

A seconda dello scenario che si potrebbe cambiare la convalida per accadere solo su aggiornamento. Esempio: :validates :expire_date, :presence => true, :on => [:update ]

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top