我有很多可以授权的模型(有作者字段)和/或可租用(有租户字段)。所以,我写了两个问题。
问题出在测试中。我曾使用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
这段代码在所有可租赁和可授权的模型的工厂中应该是相同的。
我没有找到任何办法。有可能吗?
答案 0 :(得分:12)
Traits可以在全球注册,这样它们就可以在任何其他工厂中使用,而无需使用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)
after
回调也可以全局注册,但这意味着它们会被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
请注意,此处需要明确指定model
工厂的类才能使其工作。您现在可以构建对象:
FactoryGirl.build(:model, :no_author) # Happiness!
FactoryGirl.build(:other_model) # More Happiness!
使用第二种方法,特征和回调更加包含。当您拥有包含许多工厂的大型代码库时,这实际上可能会减少意外情况。