2010-04-19 11 views
22

Ho bisogno di passare argomenti extra a factory girl da utilizzare in un callback. Qualcosa di simile (ma più complesso in realtà):Argomenti aggiuntivi per Factory Girl

Factory.define :blog do |blog| 
    blog.name "Blah" 

    blog.after_create do |blog| 
    blog.posts += sample_posts 
    blog.save! 
    end 
end 

e quindi creare con qualcosa di simile:

Factory.create(:blog, :sample_posts => [post1, post2]) 

Delle idee come farlo?

risposta

32

Questo è ora possibile senza "hack", grazie agli attributi transitori (see comment on issue #49)

esempio:

FactoryGirl.define do 
    factory :user do 
    transient do 
     bar_extension false 
    end 
    name {"foo #{' bar' if bar_extension}"} 
    end 
end 

# Factory(:user).name = "foo" 
# Factory(:user, :bar_extension => true).name = "foo bar" 

Per le versioni Factory Girl < 5.0:

FactoryGirl.define do 
    factory :user do 
    ignore do 
     bar_extension false 
    end 
    name {"foo #{' bar' if bar_extension}"} 
    end 
end 

# Factory(:user).name = "foo" 
# Factory(:user, :bar_extension => true).name = "foo bar" 
+3

Utile set di documenti qui, incluso come accedere a un attributo transitorio da un after_create o altro blocco: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md – Hollownest

+1

'ignore' è deprecato. Usa invece 'transient'. –

+0

@JonathanTran Grazie mille, ho modificato la mia risposta per riflettere i cambiamenti! – wintersolutions

2

Una possibilità sarebbe quella di creare una funzione di accesso virtuale per posti supplementari che i controlli after_create gancio:

class Blog 
    has_many :posts 
    attr_accessible :name, :title, ... # DB columns 
    attr_accessor :sample_posts  # virtual column 
end 

Factory.define :blog do |blog| 
    blog.name 'Blah' 

    blog.after_create do |b| 
    b.posts += b.sample_posts 
    b.save! 
    end 
end 

Factory(:blog, :sample_posts => [post1, post2]) 
+0

Per il mio esempio, che avrebbe funzionato, il mio vero caso è un po 'più complicato. Inoltre, non mi piacciono i modelli inquinanti per i limiti di FactoryGirl. Grazie comunque :) – Pablo

+1

Hai solo bisogno di inquinare il modello nel tuo ambiente 'test'. In effetti, puoi farlo direttamente in 'factories.rb'. –

+0

Oh! ovviamente, classi aperte :) – Pablo

1

Un'altra opzione sarebbe quella di utilizzare build invece di create e aggiungere :autosave alla collezione:

class Blog 
    has_many :posts, :autosave => true 
end 

Factory.define :blog do |blog| 
    blog.name 'Blah' 
    blog.posts { |_| [Factory.build(:post)] } 
end 

Factory(:blog, :posts => [post1, post2]) 
#or 
Factory.build(:blog, :posts => [unsavedPost1, unsavedPost2]) 
1

se si sta aprendo la classe all'interno del file factorygirl, suggerisco di farlo come

require "user" 
class User 
    attr :post_count 
end 

in modo che si sta aprendo la classe, invece di sovrascriverlo

Problemi correlati