我是FactoryGirl的新手,我正在尝试以下简单的场景?
factory :female,:class => Gender do code 'Female' end factory :male,:class => Gender do code 'Male' end factory :papas,:class => Customer do first_name 'Jim' last_name 'Papas' association :gender,:factory => :male,:strategy => :build end factory :dumas,:class => Customer do first_name 'Mary' last_name 'Dumas' association :gender,:factory => :female,:strategy => :build end
然后在我的测试中:
create(:male) create(:female) create(:papas) create(:dumas)
请注意,Customer类有一个关联“belongs_to”Gender类和一个验证规则,说明“gender_id”应该存在.我也有一个验证关于性别类的唯一性的代码.
在上面的“create((papas)”语句中,在我的测试中,我收到了将要创建的Customer无效的错误,因为“gender_id”为nil.
如果我删除了“:strategy =>:build”在Customer:Papas工厂协会与性别,那么我会收到一个错误,当尝试创建:papas,性别的代码已经存在.
我需要做什么,以便我的测试创建如上所述的数据?
请注意,我想在没有客户的情况下创建性别,在其他测试中.不要告诉我用工厂创建命令创建客户,让客户同时创建性别.如果我尝试创造两个相同性别的客户,这将不会奏效.
还有一个比一个更好的答案:
@male = create(:male) @female = create(:female) create(:papas,:gender => @male) create(:dumas,:gender => @female)
(当使用灯具时,这些东西已经准备就绪,我要回到灯具吗?)
解决方法
您可以通过不使用工厂进行性别实例并在客户工厂中使用回调来实现所需的目标.
你并没有从性别工厂那里获得很多东西(尽管我感谢它可以简化为了提出这个问题).你可以很容易地做到这一点得到一个性别:
Gender.find_or_create_by_code!('Male')
然后在您的客户工厂,您可以使用以前的回调来设置“性别”:
factory :dumas,:class => Customer do first_name 'Mary' last_name 'Dumas' before_create do |customer| customer.gender = Gender.find_or_create_by_code!('Female') end end
最近更改了在factory_girl中使用回调的格式,如果您使用3.3或更高版本,则需要执行以下操作:
before(:create) do |customer|
而不是before_create.
如果创建性别比您的示例更复杂,您仍然可以使用工厂创建性别,然后使用find_by_code与使用回调的客户联系起来. find_or_create_by_code!的insteand.