我有许多模型可以是authorable(有作者字段)和/或tenancyable(有租户字段).所以,我写了两个问题.
问题出在测试中.我曾使用shared_examples_for块为关注点编写测试,并将它们包含在我的模型测试中.无论如何,要做到这一点,我有几个特征和后块,例如:
after(:build) do |authorable| authorable.author = build(:user,tenant: authorable.tenant) end trait :no_author do after(:build) do |authorable| authorable.author = nil end end trait :no_tenant do tenant nil end
在所有可租赁和可授权的模型的工厂中,这段代码应该是相同的.
我没有找到任何办法做到这一点.可能吗?
解决方法
特征可以在全球注册,因此它们可以在任何其他工厂中使用,而无需使用FactoryGirl的继承:
FactoryGirl.define do trait :no_author do after(:build) { |authorable| authorable.author = nil } end trait :no_tenant do tenant nil end factory :model do tenant { build(:tenant) } end end
然后,您可以像这样简单地构建对象:
FactoryGirl.build(:model,:no_tenant) FactoryGirl.build(:model,:no_author)
回调后也可以全局注册,但这意味着它们会被FactoryGirl创建的任何对象触发,这可能会导致不良的副作用:
FactoryGirl.define do after(:build) do |authorable| authorable.author = build(:user,tenant: authorable.tenant) end factory :model do tenant { build(:tenant) } end factory :other_model end FactoryGirl.build(:model) # Happiness! FactoryGirl.build(:other_model) # undefined method `tenant'
为避免这种情况,您可以将回调包装在特征中,就像在:no_author特征中一样,或者您可以使用工厂继承:
FactoryGirl.define do factory :tenancyable do trait :no_tenant do tenant nil end factory :authorable do after(:build) do |authorable| authorable.author = build(:user,tenant: authorable.tenant) end trait :no_author do after(:build) do |authorable| authorable.author = nil end end end end factory :model,parent: :authorable,class: 'Model' do tenant { build(:tenant) } end factory :other_model end
请注意如何在此处明确指定模型工厂的类以使其工作.您现在可以构建对象:
FactoryGirl.build(:model,:no_author) # Happiness! FactoryGirl.build(:other_model) # More Happiness!