Factory Девушка создает связь с существующим объектом
Я новичок в FactoryGirl, и я пробую следующий простой сценарий?
factory :female, :class => Gender do
code 'Female'
end
factory :male, :class => Gender do
code 'Male'
end
factory :papas, :class => Customer do
first_name 'Jim'
last_name 'Papas'
association :gender, :factory => :male, :strategy => :build
end
factory :dumas, :class => Customer do
first_name 'Mary'
last_name 'Dumas'
association :gender, :factory => :female, :strategy => :build
end
Тогда в моем тесте:
create(:male)
create(:female)
create(:papas)
create(:dumas)
Обратите внимание, что класс Customer имеет ассоциативный класс belongs_to
Gender
и правило проверки, в котором указано, что gender_id
должен присутствовать. У меня также есть проверка на класс Gender
для уникальности кода.
В инструкции create(:papas)
выше, в моем тесте, я получаю сообщение об ошибке, что создаваемый Customer
недействителен, потому что gender_id
- nil
.
Если я удалю связь :strategy => :build
с Customer
:papas
factory с полом, то я получу ошибку, что при попытке создать :papas
код для пола уже существует.
Что мне нужно сделать, чтобы мои тесты создавали данные, как указано выше?
Обратите внимание, что я хочу, чтобы гендерные группы были созданы без клиентов, а также в других тестах. Не говорите мне, чтобы создавать клиентов с помощью factory создавать команды и позволять клиентам создавать гендерные группы одновременно. Это не сработает, если я попытаюсь создать двух клиентов того же пола.
Кроме того, должен быть лучший ответ, чем тот:
@male = create(:male)
@female = create(:female)
create(:papas, :gender => @male)
create(:dumas, :gender => @female)
(При использовании приспособлений эти вещи были готовы из коробки. Должен ли я вернуться к светильникам?)
Ответы
Ответ 1
Вы можете достичь того, чего хотите, не используя factory для своих экземпляров Gender и используя обратные вызовы в вашем клиенте factory.
Вы не получаете много от Гендерного factory в его нынешнем виде (хотя я ценю, что это может быть упрощено с целью задать этот вопрос). Вы можете так же легко сделать это, чтобы получить пол:
Gender.find_or_create_by_code!('Male')
Затем в вашем Customer factory вы можете использовать перед обратным вызовом, чтобы установить пол:
factory :dumas, :class => Customer do
first_name 'Mary'
last_name 'Dumas'
before_create do |customer|
customer.gender = Gender.find_or_create_by_code!('Female')
end
end
Формат использования обратных вызовов в factory_girl недавно изменился, поэтому, если вы используете 3.3 или более позднюю версию, вам нужно будет сделать:
before(:create) do |customer|
вместо before_create
.
Если создание пола более сложно, чем ваш пример, вы все равно можете создать гендерные группы с помощью factory, но подключите их к своим клиентам с помощью обратных вызовов с помощью find_by_code!
insteand find_or_create_by_code!
.
Ответ 2
Блок ignore
можно также использовать для обертывания:
factory :dumas, :class => Customer do
ignore do
female { Gender.find_by_code('Female') || create(:female) }
end
first_name 'Mary'
last_name 'Dumas'
gender { female }
end
Ответ 3
ignore
устарел и будет удален на версии 5 из Factory Girl.
Вместо этого вы можете использовать переходные атрибуты:
factory :dumas, :class => Customer do
transient do
female { Gender.find_by_code('Female') || create(:female) }
end
first_name 'Mary'
last_name 'Dumas'
gender { female }
end