Blog ยป Factory Girl for Rails can do more…
Posted on 25 Jun 2009 13:31
Ignore this whole article. Lastest versions of FactoryGirl are capable without tricks. Just go for the latest…
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:
Update: Factory girl implementation has greatly changed since the writing of this article. So here is how it would be in FactoryGirl 4.0.0 . I'll convert the whole article as soon as I have time :
factory :child do sequence(:name) {|n| "Child#{n}"} class << @definition def default_parent @default_parent ||= FactoryGirl.build(:parent) end end parent_id { @definition.default_parent.id } end
(This is the outdated syntax)
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:
You can contact me if you have questions or corrections.