【问题标题】:Create factory for deeply nested models为深度嵌套模型创建工厂
【发布时间】:2012-11-09 22:36:16
【问题描述】:

在我犯罪的那段时间里,我已经使用 Rails 快 4 年了。我从来没有写过一个测试。不知道为什么我花了这么长时间才看到我一直在犯的巨大错误,但我现在知道了。我想改变我的开发并开始使用 TDD。但要做到这一点,我必须为我目前正在开发的应用程序建立一个测试套件。我已经设置了 rspec 和 factory_girl 并开始了解一些事情。我有一些相当复杂的模型正在尝试测试,但我被卡住了。这是我所拥有的:

class BusinessEntity
  has_many :business_locations

class BusinessLocation
   belongs_to :business_entity
   has_many :business_contacts

   validates :business_entity_id, :presence => true

class BusinessContact
   belongs_to :business_location
   has_many :business_phones

   validates :business_location_id, :presence => true

class BusinessPhone
    belongs_to :business_contact

    validates :business_contact_id, :presence => true

在这些模型中还有更多内容,但这就是我所坚持的。如何为 business_entity 创建一个工厂来构建所有必需的孩子?因此,在规范文件中,我可以只使用 FactoryGirl.create(:business_entity) 并能够将其用于其他模型测试。 我有这个工厂

    require 'faker'

FactoryGirl.define do
  factory :business_entity do
    name "DaveHahnDev"        
  end

  factory :business_location do
    name "Main Office"
    business_entity
    address1 "139 fittons road west"
    address2 "a different address"
    city { Faker::Address.city }
    province "Ontario"
    country "Canada"
    postal_code "L3V3V3"
  end

  factory :business_contact do
    first_name { Faker::Name.first_name}
    last_name { Faker::Name.last_name}
    business_location
    email { Faker::Internet.email}
  end

  factory :business_phone do
    name { Faker::PhoneNumber.phone_number}
    business_contact
    number_type "Work"
  end
end

通过这个

require 'spec_helper'


  it "has a valid factory" do
    FactoryGirl.build(:business_entity).should be_valid
  end

那么我如何使用这个工厂来创建包含所有子项的 business_entity 以用于其他规范测试。

我希望这足够清楚,任何帮助将不胜感激

【问题讨论】:

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


    【解决方案1】:

    如果我理解正确,您需要创建关联。使用 FactoryGirls 执行此操作的最基本方法是将工厂名称添加到另一个工厂块中。因此,在您的情况下,它将如下所示:

    # factories.rb
    
    FactoryGirl.define do
      factory :business_entity do
        name "DaveHahnDev"        
      end
    
      factory :business_location do
        business_entity # this automatically creates an association
        name "Main Office"
        business_entity
        address1 "139 fittons road west"
        address2 "a different address"
        city { Faker::Address.city }
        province "Ontario"
        country "Canada"
        postal_code "L3V3V3"
      end
    
      factory :business_contact do
        business_location
        first_name { Faker::Name.first_name}
        last_name { Faker::Name.last_name}
        business_location
        email { Faker::Internet.email}
      end
    
      factory :business_phone do
        business_contact
        name { Faker::PhoneNumber.phone_number}
        business_contact
        number_type "Work"
      end
    end
    

    添加这些行后,您可以调用 FactoryGirl.create(:business_location),它将创建一个新的 BussinessLocation 记录、BussinessEntity 记录并将它们关联起来。

    更多详细信息请查看FactoryGirls Wiki - Associations

    【讨论】:

    • it "should have a location" do entity = FactoryGirl.create(:business_entity) entity.business_locations.size.should_not eq(0) end 这正常吗?在另一个规范文件中,我需要一个包含所有子对象的整个 business_entity 对象这可能吗?
    • 是的,没错。假设您使用的是我的示例,使用 FactoryGirls.create(:business_entity) 您将只获得没有关联的 BussinessEntity 实例。但是如果要获取关联,则需要将其他关联直接添加到 bussiness_entity 工厂中。
    • 你可以写factory :business_entity do name "DaveHahnDev" factory :business_entity_with_locations do after(:build) do |business_entity| business_entity.business_locations << FactoryGirl.build(:business_location) end end,然后调用你的测试FactoryGirl.create(:business_entity_with_locations)
    • 太棒了。我一回到家就试试这个。非常感谢您的帮助。我开始看到先写测试的价值了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    • 1970-01-01
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 2014-02-24
    • 1970-01-01
    相关资源
    最近更新 更多