Заводы Singleton в factory_girl/машинисте?
Есть ли какая-то конфигурация в factory девушки/машиниста factory, которая заставляет его создавать объекты с тем же именем factory только один раз во время тестового случая и все время возвращать один и тот же экземпляр? Я знаю, я могу сделать что-то вроде:
def singleton name
@@singletons ||= {}
@@singletons[name] ||= Factory name
end
...
Factory.define :my_model do |m|
m.singleton_model { singleton :singleton_model }
end
но, возможно, есть лучший способ.
Ответы
Ответ 1
Вы можете использовать макрос initialize_with
внутри вашего factory и проверить, существует ли объект, но не создавать его снова. Это также работает, когда упомянутый factory ссылается на ассоциации:
FactoryGirl.define do
factory :league, :aliases => [:euro_cup] do
id 1
name "European Championship"
owner "UEFA"
initialize_with { League.find_or_create_by_id(id)}
end
end
Здесь есть аналогичный вопрос с большим количеством альтернатив: Использование factory_girl в Rails с ассоциациями, которые имеют уникальные ограничения. Получение повторяющихся ошибок
Ответ 2
Не уверен, что это может быть полезно для вас.
С помощью этой установки вы можете создать n продуктов с помощью factory 'singleton_product'. Все эти продукты будут иметь одну и ту же платформу (например, платформу FooBar).
factory :platform do
name 'Test Platform'
end
factory :product do
name 'Test Product'
platform
trait :singleton do
platform{
search = Platform.find_by_name('FooBar')
if search.blank?
FactoryGirl.create(:platform, :name => 'FooBar')
else
search
end
}
end
factory :singleton_product, :traits => [:singleton]
end
Вы можете использовать стандартный продукт factory "продукт" для создания продукта с платформой "Test Platform", но он будет терпеть неудачу, когда вы вызываете его для создания второго продукта (если имя платформы задано как уникальное).
Ответ 3
@CubaLibre ответ с версией 5 FactoryBot:
FactoryGirl.define do
factory :league do
initialize_with { League.find_or_initialize_by(id: id) }
sequence(:id)
name "European Championship"
end
end