Ruby on rails 与RSpec/FactoryGirl建立嵌套关联的最佳方法
我正在尝试为Rails应用程序构建一个测试套件,但我不确定如何使用FactoryGirl构建对象(如果需要,我可以使用其他工具) 棘手的部分是存在深层嵌套关联,让我们以模式的这一部分为例: 假设我想在“ItemTracker”模型上做一些测试。现在有两种方法:Ruby on rails 与RSpec/FactoryGirl建立嵌套关联的最佳方法,ruby-on-rails,rspec,factory-bot,Ruby On Rails,Rspec,Factory Bot,我正在尝试为Rails应用程序构建一个测试套件,但我不确定如何使用FactoryGirl构建对象(如果需要,我可以使用其他工具) 棘手的部分是存在深层嵌套关联,让我们以模式的这一部分为例: 假设我想在“ItemTracker”模型上做一些测试。现在有两种方法: 为了有一个有效的对象,我需要建立一个连接,它需要一个令牌,它需要一个项目,等等。。。此外,我希望ProjectItem的项目与Token的项目相同。公司(在顶部)也是如此。我不想创建两个不同的项目或公司。所以我需要一种方法让这些对象共享
- 为了有一个有效的对象,我需要建立一个连接,它需要一个令牌,它需要一个项目,等等。。。此外,我希望ProjectItem的项目与Token的项目相同。公司(在顶部)也是如此。我不想创建两个不同的项目或公司。所以我需要一种方法让这些对象共享一些关联。这种方法的一个缺点是,我不知道如何确保不创建多个关联对象,而且我还将构建大量不一定需要的对象(验证除外)
- 我可以说“对于这个特殊的测试,关联是不相关的,所以我只需要创建一个ItemTracker,没有它的连接或投影项,用这个孤立的对象来做我的事情”。一般来说,我只需要创建实际需要的对象和关联。通过玩弄特质,我找到了一种方法,如果我不需要它们,可以避免产生联想。缺点是这个对象无效(关联上有验证),所以每次我试图在它上保存一些东西时,我都会遇到一个异常,这在一些测试用例中是一个难题
感谢您的反馈;) 无论如何,您都需要构建整个关系树,但您可以将其放入一个trait中,例如,在specs中,使用trait
和所有关系创建项目跟踪器。它看起来是这样的:
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
如果你没有指定任何特征,你会得到没有任何相关模型的物品跟踪器
我希望ProjectItem的项目与Token的项目相同
项目公司(在顶部)也是如此。我不想有两个
创建不同的项目或公司
通过使用
覆盖初始化\u,可以使用“命名”工厂:
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
并在不同模型的关联中获得相同的项目
请注意,这气味有点像夹具,所以你可以考虑夹具是否比工厂对你的情况更好。
我只需要创建我真正需要的对象和关联。通过玩弄特质,我找到了一种方法,如果我不需要它们,可以避免产生联想。缺点是此对象无效
我建议为每个工厂创建一个“基本”版本,只允许您设置属性,而无需关联,即使这是无效的。然后通过添加关联来扩展它以创建有效(可能无效)的版本。这是一个很好的例子