2011-04-01 70 views
20

如何創建同一班級的多個記錄或多個工廠?如何在Factory Girl中創建/構建工廠的多個實例?

我想:

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

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

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 

但它不工作 - Attribute already defined: email

回答

19

使用工廠有兩個步驟,第一步是定義它們,第二步是使用它們。

1)定義它們:

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

2)使用它們:

一個例子是使用它們的規格:

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

我看這個Railscast到對它有更好的感覺。

+0

非常感謝,我接受你的答案在幾分鐘內! ;) – benoitr 2011-04-01 06:25:42

+0

好運@benoitr! – 2011-04-01 06:26:14

39

這是一個老問題和答案,但它是第一個結果,我在谷歌找到,所以我想我要補充從docs下面的標題下,建築物或創建多個記錄

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 

在我剛剛引用的例子中,每個用戶都有不同的用戶名,前提是在工廠定義中使用了sequence(請參閱Mike Lewis上面的答案)。

+0

太棒了!感謝您回到一個老問題並給出最新的答案。 – 2016-02-20 21:30:58

26

如果您希望來自同一(基地)工廠的記錄具有不同的值,有幾個選項。定義

A)覆蓋屬性

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

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

B)繼承

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)序列

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

d)性狀

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) 

這些方法可以進行組合。這個例子使用列表和序列對並重寫。

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) 

我更喜歡儘可能使用特質,我覺得它們很靈活。

0

與當前factory_girl_rails 4.6.0我有某種相關的問題,build(:model)總是返回對象的同一個實例。使用sequence(:name) ...沒有解決這個問題。於是,我產生了一些假的(空)的特徵是這樣的:

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 

,然後調用build(:model, :var1), build(:model, :var2)...

相關問題