【问题标题】:Best way to set up nested associations with RSpec / FactoryGirl使用 RSpec / FactoryGirl 设置嵌套关联的最佳方式
【发布时间】:2015-12-07 10:20:53
【问题描述】:
我正在尝试为 Rails 应用程序构建测试套件,但我不确定如何使用 FactoryGirl 构建对象(如果需要,我可以使用其他工具)。
棘手的部分是存在深层嵌套关联,让我们以架构的这一部分为例:http://imgur.com/HAUS7kr
假设我想对“ItemTracker”模型进行一些测试。现在有两种方法:
所以我想我的问题是:在这种复杂的对象结构中设置一些对象进行测试的最佳方法是什么?
感谢您的反馈;)
【问题讨论】:
标签:
ruby-on-rails
rspec
factory-bot
【解决方案1】:
无论如何,您都需要构建整个关系树,但您可以将其放入特征中,并在规范中创建具有特征with_all_relations 的项目跟踪器,例如。它看起来像这样:
FactoryGirl.define do
factory :item_tracker do
...
trait :with_all_relations do
after(:build) do |item_tracker|
company = create(:company)
item = create(:item, company: company)
user = create(:user, company: company)
...
item_tracker.project_item = project_item
item_tracker.connexion = connexion
end
end
end
end
如果您不指定任何特征,您将获得没有任何相关模型的项目跟踪器。
【解决方案2】:
我希望 ProjectItem 的项目与 Token 的项目相同
项目。与公司相同(在顶部)。我不想拥有 2
创建了不同的项目或公司
您可以通过覆盖 initialize_with 来使用“命名”工厂:
factory :project do
# define common attributes for projects
factory :project_1 do
initialize_with do
Project.find_or_create_by(name: "Project 1")
end
end
end
现在您可以通过关联添加:
association :project, factory: project_1
并在不同模型的关联中获得相同的项目。
请注意,这闻起来很像夹具,因此您可以考虑夹具是否比工厂更适合您的情况。
我只会创建我真正需要的对象和关联。通过使用特征,我找到了一种在不需要时避免创建关联的方法。缺点是这个对象不会是有效的
我建议为每个工厂创建一个“基本”版本,它只允许您设置属性,而无需关联,即使这是无效的。然后通过添加关联来扩展它以创建有效(和可能无效)的版本。 Jeiwan's answer 就是一个很好的例子。