Factory Girl for Rails can do more...

Blog » Factory Girl for Rails can do more…

Posted on 25 Jun 2009 13:31

icon-factorygirl.png

Unit testing with FactoryGirl is very DRY. The power of Ruby enables you to do more cool and elaborate things with factories. Factories can be equipped with useful custom methods. Let's define a child factory that always uses the same default parent:

Factory.define :child do |f|
    f.sequence(:name) {|n| "Child#{n}"}
 
    def f.default_parent
        @default_parent ||= Factory(:parent)
    end
 
    f.parent_id { f.default_parent.id }
end

Now every child created will have the same default parent. Instead of abusing the global space, instead of having to modify class Factory, the method and variable its using is neatly included in the factory instance.

And whenever you want, you can use another parent in the tests.

child = Factory(:child, :parent_id=another_parent.id)

But the default child will come with the single default parent. More speed and space

child1 = Factory(:child)
child2 = Factory(:child)
# child1.parent == child2.parent

You can access the custom method elsewhere

f =  Factory.factory_by_name(:child)
f.default_parent

As you see, you can treat the factories like classes - with custom methods and properties. This allows possibilities which are not evident from the syntax of Thoughtbot Factory Girl

Remember. In Ruby, object instances can have their custom methods!

To be able to do whatever you can do in a normal class declaration, here is an alternative syntax:

Factory.define :child do |f|
 
    class << f
        #do whatever you can do in a normal class definition
        def default_parent
            @default_parent ||= Factory(:parent)
        end
    end
 
    f.sequence(:name) {|n| "Child#{n}"}
    f.parent_id { f.default_parent.id }
end

Thoughtbot Factory Girl will allow you write your tests easier than using fixtures.

Happy unit testing… Don't forget to use Shoulda!

If you like this page, please spread the word: diggdel.icio.usFacebook

As well as commenting here, you can tweet or email to me

Add a New Comment
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License