Dave Hahn
Dave Hahn

Reputation: 115

Create factory for deeply nested models

I have been using rails for almost 4 years now in in all that time I have been sinning. I have never written a single test. Not sure why it has taken me this long to see the giant mistake I have been making but I have now. I want to change my development around and start utilizing TDD. But to do that I have to build up a test suit for the application I am currently working on. I have got rspec and factory_girl setup and am starting to understand things abit. I have some fairly complex models I am trying to test and I am stuck. Here is what I have:

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

There is more going on in these models but this is what I am stuck on. How can I create a factory for business_entity that builds all required children? So in the spec file I can just FactoryGirl.create(:business_entity) and be able to use this for other model testing. I have this factory

    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

This passes this

require 'spec_helper'


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

So how can I use this factory to create the business_entity with all children for use in other spec tests.

I hope this is clear enough and any help would be greatly appreciated

Upvotes: 3

Views: 2090

Answers (1)

tokenvolt
tokenvolt

Reputation: 1494

If I've understood correctly you need to create associations. The most basic way to do this using FactoryGirls is just to add the factory name in another factory block. So, in your case it will be the following:

# 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

After adding these lines you can call FactoryGirl.create(:business_location), which will create a new BussinessLocation record, BussinessEntity record and associate them.

For more detailed information check FactoryGirls Wiki - Associations

Upvotes: 2

Related Questions