我正在尝试为Rails应用程序构建测试套件,并且我不确定如何使用FactoryGirl构建对象(如果需要,我可以移动到其他工具)。
棘手的部分是有深层嵌套关联,让我们举例说明架构的这一部分:http://imgur.com/HAUS7kr
让我们说我想对" ItemTracker"进行一些测试。模型。现在有两种方法:
为了拥有一个有效的对象,我需要构建一个需要一个Token的Connexion,它需要一个Project等等。另外,我希望ProjectItem的项目是与Token的项目相同。与公司相同(在顶部)。我不想创建2个不同的项目或公司。所以我需要一种方法让这些对象共享一些关联。这种方法的一个缺点是我不确定如何创建不创建多个相关对象,而且我还要构建大量我不一定需要的对象(验证除外)< / p>
我可以说&#34;对于这个特定的测试,关联是无关紧要的,所以我要创建一个没有Connexion或ProjectItem的ItemTracker,用这个孤立的对象做我的事情&# 34 ;.一般来说,我只想创建我真正需要的对象和关联。通过玩特质,我发现了一种避免创建关联的方法,如果我不需要它们。缺点是这个对象无效(有关联的验证),所以每次我试图在其上保存一些东西时,我都会有一个例外,这将是一个痛苦的一些测试用例。
所以我想我的问题是:在这种复杂的对象结构中设置一些对象进行测试的最佳方法是什么?
感谢您的反馈;)
答案 0 :(得分:2)
无论如何,您需要构建整个关系树,但是您可以将其置于特征中,并在规范中创建具有特征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
如果您没有指定特征,您将获得没有任何相关模型的项目跟踪器。
答案 1 :(得分:1)
我希望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就是一个很好的例子。