Зависимые фабрики в Factory Девушка
У меня есть 2 фабрики. Beta_user и Beta_invite. В принципе, до того, как Beta_user может сэкономить, мне нужно создать запись Beta_invite. К сожалению, эти модели не имеют чистых ассоциаций, но они действительно используют поле электронной почты.
Factory.sequence :email do |n|
"email#{n}@factory.com"
end
#BetaInvite
Factory.define :beta_invite do |f|
f.email {Factory.next(:email)}
f.approved false
f.source "web"
end
#User
Factory.define :user do |f|
f.email {Factory.next(:email)}
f.password "password"
end
#User => BetaUser
Factory.define :beta_user, :parent => :user do |f|
f.after_build do |user|
if BetaInvite.find_by_email(user.email).nil?
Factory(:beta_invite, :email => user.email)
end
end
end
Итак, в бета-версии beta_user factory я пытаюсь использовать обратный вызов after_build для создания бета-версии factory.
Однако это похоже на асинхронное действие или что-то в этом роде. Возможно, вы выбрали find_by_email?
Если я попробую это:
Factory(:beta_user)
Factory(:beta_user)
Factory(:beta_user)
Я получаю отказ, заявляя, что нет записи о бета-версии с этим электронным письмом пользователей.
Если я попробую:
Factory.build(:beta_user).save
Factory.build(:beta_user).save
Factory.build(:beta_user).save
Я получаю лучшие результаты. Как будто вызов метода .build и ожидание сохранения позволяет создавать бета-версию factory. Вместо прямого вызова factory.create. Документы говорят, что в случае вызова factory.create вызываются вызовы after_build и after_create.
Любая помощь очень ценится.
UPDATE:
Таким образом, модель User, которую я использую, вызывает вызов before_validation
к методу, который проверяет, есть ли бета-приглашение. Если я переведу этот вызов метода на before_save
. Он работает правильно. Есть что-то, над чем я смотрю. Когда factory_girl запускает обратные вызовы after_build
и after_create
по отношению к активной записи before_validation
и before_save
?
Ответы
Ответ 1
Мне кажется, что он просто должен работать, но у меня были проблемы с ассоциациями в Factory -girl. Подход, который мне нравится использовать в таком случае, если отношения менее очевидны, заключается в определении специального метода внутри вашего factory следующим образом:
def Factory.create_beta_user
beta_invite = Factory(:beta_invite)
beta_user = Factory(:user, :email => beta_invite.email)
beta_user
end
и использовать это в своих тестах, просто напишите
Factory.create_beta_user
Надеюсь, что это поможет.
Ответ 2
Не уверен, что это поможет вам, но это код, который я использовал:
# Create factories with Factory Girl
FactoryGirl.define do
# Create a sequence of unique factory users
sequence(:email) { |n| "factoryusername+#{n}@example.com"}
factory :user do
email
password "factorypassword"
# Add factory user email to beta invite
after(:build) {|user| BetaInvite.create({:email => "#{user.email}"})}
end
end