Как создать/создать несколько экземпляров factory в 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
.
Ответы
Ответ 1
Существует два способа использования фабрик, первый - их определение, а второй - их использование.
1) Определите их:
Factory.define :user do |u|
u.sequence(:email) { |n| "mike#{n}@awesome.com"}
u.password "password123"
end
2) Использование Them:
Примером может быть использование их в спецификации:
@user1 = Factory(:user) #has an email of [email protected]
@user2 = Factory(:user) # has an email of [email protected] due to sequences in FG
Я бы посмотрел этот Railscast, чтобы лучше понять его.
Ответ 2
Это более старый вопрос и ответ, но это был первый результат, который я нашел в Google, поэтому я решил добавить следующее из документов под заголовком Создание или создание нескольких записей:
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
Если вы хотите запустить это в консоли rails, рассмотрите следующий ответ здесь: fooobar.com/questions/96124/...
В приведенном мною примере у каждого пользователя будет свое имя, при условии, что эта sequence
используется в определении фабрики (см. Ответ Майка Льюиса выше).
Ответ 3
Есть несколько вариантов, если вы хотите, чтобы записи из того же (базового) factory имели разные значения.
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)
Я предпочитаю использовать черты, когда это возможно, я нахожу их гибкими.
Ответ 4
С текущим 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)...