В чем разница между методами сборки и создания в FactoryGirl?

96

Во вступлении Factory Girl подчеркивается разница между FactoryGirl.build()и FactoryGirl.create():

# Returns a User instance that's not saved
user = FactoryGirl.build(:user)

# Returns a saved User instance
user = FactoryGirl.create(:user)

Я до сих пор не понимаю практических различий между ними. Может ли кто-нибудь привести пример, в котором вы хотели бы использовать одно, а не другое? Благодарность!

Эйвери
источник

Ответы:

120

create()Метод сохраняется экземпляр модели в то время как build()метод сохраняет его только на память.

Лично я использую этот create()метод только тогда, когда настойчивость действительно необходима, так как запись в БД требует много времени на тестирование.

например

Я создаю пользователей для аутентификации, create()потому что мой механизм аутентификации запрашивает БД.

Чтобы проверить, есть ли у модели атрибут, этот build()метод будет делать, потому что доступ к БД не требуется.

it{Factory.build(:user).should respond_to(:name)}

Обновить

«Есть одно исключение: build на самом деле« создает », когда вы создаете ассоциации, то есть ваши ассоциации больше не в памяти, а сохраняются. Имейте это в виду», - Shakes

Хелио Сантос
источник
16
Есть одно исключение: build фактически «создает», когда вы строите ассоциации, то есть ваша ассоциация больше не находится в памяти, а сохраняется. Имейте это в виду
Shakes
@ Shakes, я больше не работаю в рельсах. Я проверю это, как только смогу.
Helio Santos
Кто - нибудь сделал инструмент для замены каждого экземпляра createс build, и отменить его , если тест не пройден?
mgold
Читает #createи возвращает сохраненный объект с диска или возвращает объект, который находится в памяти, после его сохранения? Другими словами, это create(...)эквивалентно create(...).reload?
Деннис
@mgold Vim неплохо справляется с подобными вещами.
Ограниченное искупление,
15

Использование FactoryGirl.build(:factory_name)не сохраняется в базе данных и не вызывает save!, поэтому ваши проверки Active Record не будут выполняться. Это намного быстрее, но проверки могут быть важны.

Использование FactoryGirl.create(:factory_name)будет сохраняться в базе данных и вызовет проверки Active Record. Это, очевидно, медленнее, но может обнаруживать ошибки проверки (если вы заботитесь о них в своих тестах).

пропасть
источник
11
Или вы можете просто сделать FactoryGirl.build (: factory_name) .valid? которые запускают проверки без сохранения в базе данных.
jinavar1
1

FactoryGirl.create()создаст для него новый объект и ассоциации (если они есть на фабрике). Все они будут сохранены в базе данных. Кроме того, это вызовет проверку как модели, так и базы данных. Обратные вызовы after(:build)и after(:create)будут вызываться после сохранения фабрики. Также before(:create)будет вызываться перед сохранением фабрики.

FactoryGirl.build()не будет сохранять объект, но все равно будет делать запросы к базе данных, если у фабрики есть ассоциации. Это вызовет проверки только для связанных объектов. Обратный after(:build)вызов будет вызван после того, как фабрика будет построена.

Обратите внимание, что в большинстве случаев при тестировании модели лучше всего использовать build_stubbedдля повышения производительности. Подробнее об этом читайте здесь .

Неша Зорич
источник