Factory_girl with NonActiveRecord classes

In earlier post you have seen how to test active record associations with factory girl. Now you will learn how factory girl works with non-active record classes. When you want to test external API responses, this will be useful.  By using this you can build no of responses at a time and test, how system will handle inputs. It is as similar as to working factory girl with active record classes. Now here is the way

Step1:

First you need define class and attributes of the class. For example

#spec/support/models/deal.rb
class  Deal
   attr_accessor  :title, :remainingQuantity, :price_amount
end

Step 2:

Create a directory called ‘models’ inside ‘spec/support’ directory and place this class.  Because of following line of code it will includes our class while test environment is loading.

# spec/spec_helper.rb
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

Step 3:

Now we have to create an object by using factory. Create a factory file in spec/factories directory as how we are writing factory file for a active record class. For example

#spec/factories/deal.rb
Factory.define :deal do |g|
    g.title               "Whisky for $10"
    g.remainingQuantity   20
    g.price_amount        10
end

Step 4:

Now use this factory in your specs. For example

#spec/models/deal_spec.rb
deal = Factory.build(:deal)

It will return an object of class Deal. Now it works as a normal ruby object and we can apply our conditions on it. For more see factory_girl

I hope everyone enjoyed this article. Any comments would be welcome.

Advertisements

Testing associations with factory girl

Associations are very important when we are working with relational databases. Writing relations in models is easy but when it comes testing them, it is a painful task. Factory girl associations makes this easy. Before going into details, lets get the basics right.

What is Factory Girl?

Factory_girl is a fixtures replacement with a straightforward definition syntax, support for multiple build strategies (saved instances, unsaved instances, attribute hashes, and stubbed objects), and support for multiple factories for the same class (user, admin_user, and so on), including factory inheritance. Read more of it here

Testing Assocations:

has_one association Scenario : “user location” has one “email preference” There are two ways to implement this. You could define relation in user location factory. First the factory creates the email preference object and then it creates user location object.

# spec/factories/user_location.rb

Factory.define :user_location , :class => UserLocation do |ul|
   ul.email_preference { |ul| ul.association(:email_preference) }
end

You could alternatively define the same association in email preference factory. First the factory creates user location object and then it creates email preference object.

# spec/factories/email_preference.rb

Factory.define :email_preference , :class => EmailPreference do |ep|
   ep.association :user_location
end

has_many association Scenario: “City” has many “deals” Note, the factory automatically creates the deal object and then it creates city object and associates the two.

# spec/factories/city.rb

Factory.define :city, :class => City do |c|
    c.deals { |d| [d.association(:deal)] }
end

has_many => through association Scenario : “User” has many contests “through” ads First the factory creates contest object and user object and then it creates ad object.

# spec/factories/ad.rb

Factory.define :ad, :class => Ad do |ad|
   ad.association :contest
   ad.association :user
end

(or) First the factory creates ‘user’ object and then it creates ‘ad’ object and then it creates ‘contest’ object.

# spec/factories/contest.rb

Factory.define :contest, :class => contest do |c|
   c.ads { |ad| [ad.association(:ad)] }
end

And in ‘ad’ factory

# spec/factories/ad.rb

Factory.define :ad, class => Ad do |ad|
   ad.association :user
end

Polymorphic relations: Among all relations defining polymorphic relations is a little bit complicated task. Scenario : They are many type of ads like video, print, audio etc. So here video is one type of an ‘Ad’. First it creates ‘video’ object and then store resource type and ID in ‘ad’ object. Let’s see how we can define this in factories :

# spec/factories/ad.rb

Factory.define :ad, :class => Ad do |ad|
    ad.association :resource, :factory => 'video'
end

I hope this was helpful. Feedback for this would be welcome. Let me know if there is any complex scenario you found which made testing difficult. I’d like to give that a shot!