Одиночные фабрики в factory_girl / machinist? - PullRequest
13 голосов
/ 30 ноября 2010

Есть ли какая-то конфигурация на фабрике фабриканта / машиниста, которая заставляет его создавать объекты с одинаковым фабричным именем только один раз во время теста и возвращать один и тот же экземпляр все время? Я знаю, я могу сделать что-то вроде:

def singleton name
    @@singletons ||= {}
    @@singletons[name] ||= Factory name
end
...
Factory.define :my_model do |m|
   m.singleton_model { singleton :singleton_model }
end

но, может быть, есть лучший способ.

Ответы [ 3 ]

20 голосов
/ 11 июля 2012

Вы можете использовать макрос initialize_with внутри своей фабрики и проверить, существует ли объект, а не создавать его заново.Это также работает, когда на указанную фабрику ссылаются ассоциации:

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 с ассоциациями, которые имеют уникальные ограничения.Получение дубликатов ошибок

1 голос
/ 17 февраля 2012

Не уверен, что это может быть полезно для вас.

С помощью этой настройки вы можете создавать n продуктов, используя фабрику 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

Вы по-прежнему можете использовать стандартную фабрику продуктов «product» для создания продукта с платформой «Test Platform», но произойдет сбой при его вызове для создания второго продукта (если имя платформы установлено как уникальное).

0 голосов
/ 15 мая 2019

@ 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
...