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 beta_user工厂中我试图使用after_build回调来创建beta_invite工厂。
然而,它似乎是异步或其他东西。可能在做find_by_email fetch?
如果我试试这个:
Factory(:beta_user)
Factory(:beta_user)
Factory(:beta_user)
我收到一则失败声明,没有该用户发送电子邮件的beta_invite记录。
如果我尝试:
Factory.build(:beta_user).save
Factory.build(:beta_user).save
Factory.build(:beta_user).save
我得到了更好的结果。好像调用.build方法并等待保存允许创建beta_invite工厂的时间。而不是直接调用Factory.create。文档说,在调用Factory.create的情况下,调用after_build和after_create回调。
非常感谢任何帮助。
更新
因此,我正在使用的用户模型对该方法进行before_validation
调用,以检查是否存在测试版邀请。如果我将此方法调用移至before_save
。它工作正常。有什么我在看的东西。 factory_girl何时运行与活动记录after_build
和after_create
相关的before_validation
和before_save
回调?
答案 0 :(得分:11)
对我来说,它似乎应该能够工作,但我也遇到了Factory-girl中的关联问题。我喜欢在这种情况下使用的方法,如果关系不太明显,就是在工厂内部定义一个特殊方法,如下所示:
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
希望这有帮助。
答案 1 :(得分:6)
不确定这是否会对您有所帮助,但这是我使用的代码:
# 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
答案 2 :(得分:0)
我发现 this 评论给出了一个很好的例子:
term = create(:term)
period = create(:period, term: term)
candidate = create(:candidate, term: term)
我将其应用于我的情况并且可以确认它有效。