2011-04-01 16 views
20

¿Cómo creo múltiples registros o múltiples fábricas de la misma clase?¿Cómo crear/crear varias instancias de una fábrica en Factory Girl?

me trataron:

Factory.define :user do |user| 
    user.email "[email protected]" 
    user.password "somepassword" 

    user.email "[email protected]" 
    user.password "somepassword" 
end 

y

Factory.define :user do |user| 
    user.email "[email protected]" 
    user.password "somepassword" 
end 

Factory.define :user do |user| 
    user.email "[email protected]" 
    user.password "somepassword" 
end 

Pero esto no funciona - Attribute already defined: email.

Respuesta

19

Hay dos pasos para usar Fábricas, el primero es definirlos, y el segundo es usarlos.

1) definirlos:

Factory.define :user do |u| 
    u.sequence(:email) { |n| "mike#{n}@awesome.com"} 
    u.password "password123" 
end 

2) utilizarlos:

Un ejemplo sería el uso de ellos en una especificación:

@user1 = Factory(:user) #has an email of [email protected] 
@user2 = Factory(:user) # has an email of [email protected] due to sequences in FG 

Yo tendría cuidado con este Railscast a obtener una mejor sensación para ello.

+0

Muchas gracias acepto su respuesta en pocos minutos! ;) – benoitr

+0

Buena suerte @benoitr! –

39

Ésta es una pregunta más viejo y respuesta, pero fue el primer resultado que encontré en Google así que pensé que me gustaría añadir lo siguiente de la docs bajo el título construcción o creación de múltiples registros:

created_users = FactoryGirl.create_list(:user, 25) #creates 25 users 

twenty_year_olds = FactoryGirl.build_list(:user, 25, date_of_birth: 20.years.ago) #builds 25 users, sets their date_of_birth 

En el ejemplo que acabo de citar, cada usuario tendría un nombre de usuario diferente, siempre que se use sequence en la definición de fábrica (consulte la respuesta anterior de Mike Lewis).

+0

¡Brillante! Gracias por volver a una vieja pregunta y dar una respuesta actualizada. –

26

Hay un par de opciones si desea que los registros de la misma fábrica (base) tengan valores diferentes.

A) Override definido atributos

factory :post, aliases: [:approved_post] do 
    title "A title" 
    approved true 
end 

approved_post = create(:approved_post) 
unapproved_post = create(:post, approved: false) 

B) Inheritance

factory :post do 
    title "A title" 

    factory :approved_post do 
    approved true 
    end 

    factory :unapproved_post do 
    approved false 
    end 
end 

approved_post = create(:approved_post) 
unapproved_post = create(:unapproved_post) 

C) Secuencias

factory :user do 
    sequence(:email, 1000) { |n| "person#{n}@example.com" } 
end 

D) Rasgos

factory :post do 
    title "My awesome title" 

    trait(:approved) { approved true } 

    trait(:unapproved) { approved false } 

    trait :with_comments do 
    after(:create) do |instance| 
     create_list :comment, 2, post: instance 
    end 
    end 

    factory :approved_post_with_comments, traits: [:approved, :with_comments] 
end 

approved_post_with_comments = create(:approved_post_with_comments) 
unapproved_post_with_no_comments = create(:post, :unapproved, title: "Test") 
post_with_title = build(:post) 

Estos métodos se pueden combinar. Este ejemplo utiliza listas y pares con secuencias y anulación.

factory :user do 
    sequence(:username) { |n| "user#{n}" } 
    date_of_birth Date.today 
end 

# Build a pair and a list of users. 
two_newborns  = build_pair(:user) 
ten_young_adults = build_list(:user, 10, date_of_birth: 20.years.ago) 

# Create a pair and a list of users. 
two_young_adults = create_pair(:user, date_of_birth: 20.years.ago) 
ten_newborns  = create_list(:user, 10) 

Prefiero usar rasgos siempre que sea posible, los encuentro flexibles.

0

Con el actual factory_girl_rails 4.6.0 tuve el problema relacionado de alguna manera que build(:model) devolvió siempre la misma instancia del objeto.Usar sequence(:name) ... no solucionó eso. Así que me genera algunos rasgos falsos (vacío) como este:

FactoryGirl.define do 
    factory :model do 
    ... 
    # fake traits to urge factory_girl to always return a new instance: 
    (1..5).each {|n| trait "var#{n}".to_sym } 
    end 
end 

y luego llamar build(:model, :var1), build(:model, :var2)...

Cuestiones relacionadas