使用RSpec / FactoryGirl

时间:2015-12-07 10:20:53

标签: ruby-on-rails rspec factory-bot

我正在尝试为Rails应用程序构建测试套件,并且我不确定如何使用FactoryGirl构建对象(如果需要,我可以移动到其他工具)。

棘手的部分是有深层嵌套关联,让我们举例说明架构的这一部分:http://imgur.com/HAUS7kr

让我们说我想对" ItemTracker"进行一些测试。模型。现在有两种方法:

  • 为了拥有一个有效的对象,我需要构建一个需要一个Token的Connexion,它需要一个Project等等。另外,我希望ProjectItem的项目是与Token的项目相同。与公司相同(在顶部)。我不想创建2个不同的项目或公司。所以我需要一种方法让这些对象共享一些关联。这种方法的一个缺点是我不确定如何创建不创建多个相关对象,而且我还要构建大量我不一定需要的对象(验证除外)< / p>

  • 我可以说&#34;对于这个特定的测试,关联是无关紧要的,所以我要创建一个没有Connexion或ProjectItem的ItemTracker,用这个孤立的对象做我的事情&# 34 ;.一般来说,我只想创建我真正需要的对象和关联。通过玩特质,我发现了一种避免创建关联的方法,如果我不需要它们。缺点是这个对象无效(有关联的验证),所以每次我试图在其上保存一些东西时,我都会有一个例外,这将是一个痛苦的一些测试用例。

所以我想我的问题是:在这种复杂的对象结构中设置一些对象进行测试的最佳方法是什么?

感谢您的反馈;)

2 个答案:

答案 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就是一个很好的例子。