在尝试编写rSpec测试时,我对如何使用关联生成FactoryGirl记录感到困惑。
基本上,我有一个Quiz
模型和一个Question
模型。它们通过HABTM协会相关联。
这是我的Quiz
工厂:
FactoryGirl.define do
factory :quiz do
description 'Test'
# after(:create) { |quiz| quiz.create_sample_questions }
# trait :with_questions do
# after :create do |quiz|
# 5.times do |q|
# quiz.questions << FactoryGirl.create(:question, :with_answers)
# end
# end
# end
end
end
最好在这里创建特征,然后为测验创建示例问题吗?或者我应该使用after create方法来执行此操作?
似乎都没有用,我的特质似乎没有产生问题。
谢谢!
答案 0 :(得分:7)
我更喜欢使用特性,因为它们使规格更加混乱。当然,确保工厂本身不会变得过于混乱是非常重要的。
每当我定义构建关联的特征时,我都会确保我可以在关联中构建可变数量的记录,FactoryGirls可以很容易地做到这一点:
FactoryGirl.define do
factory :quiz do
description 'Test'
trait :with_questions do
ignore { question_count 5 }
questions { build_list(:question, question_count) }
end
end
end
您现在可以在规范中构建或创建quizes:
FactoryGirl.create(:quiz, :with_questions)
FactoryGirl.build(:quiz, :with_questions, question_count: 2)
请注意,该特征使用build_list
,因此默认情况下它不会保留问题,question_count
而不是questions_count
,因此它永远不会与计数器缓存冲突
为了确保您的规格不会超出他们的要求,我不会用答案来构建问题,而只是问题(除非您的验证需要它们)。如果在某些时候你确实需要答案问题,你可以添加另一个特性:
FactoryGirl.define do
factory :quiz do
description 'Test'
ignore { question_count 5 }
trait :with_questions do
questions { build_list(:question, question_count) }
end
trait :with_answered_questions do
questions { build_list(:question, question_count, :with_answers) }
end
end
end
有关使用与FactoryGirl关联的更多信息,请参阅FactoryGirl documentation。
答案 1 :(得分:3)
我有兴趣看到这个问题的其他答案,但我可以将我的个人经验与使用工厂,关联以及使用回调自动加载一堆对象联系起来。
基本上,我发现我尝试使用特征和回调的“发烧友”,我对我的规格未来造成的麻烦越多。有了这种扭曲的逻辑,你最终会遇到工厂的混乱,你会抓挠头脑,想知道到底发生了什么。
完全假设的问题:如果以后需要进行 4 问题的测验会怎么样?好吧,每个quiz
:with_questions
都包含5个问题。那么你是否创建了一个名为with_4_questions
的特征? ;)
根据我的经验,我建议您首先在规范中生成单独的模型并保持简单。不要在回调背后抽象出过多的逻辑。
因此,假设我正在使用您的模型编写功能规范。这就是我想要做的事情:
feature 'User edits a question' do
let!(:quiz) { FactoryGirl.create(:quiz) }
before do
5.times { FactoryGirl.create(:question, quiz: quiz) }
end
scenario 'with valid input' do
# ...
end
end
如果您发现自己经常需要quiz
5 question
,则可以使用Railscasts演示的方法创建macro。至少那时你可以创建一个可以将参数传递到的方法,比如上面完全假设的问题中的num_questions
。