FactoryGirl extensions
factory_girl_extensions is a simple set of syntax extensions that I typically like to use on projects when using factory_girl.
Install
gem install factory_girl_extensions
FactoryGirl extensions 2.0
As of version 2.0, factory_girl_extensions now targets the new FactoryGirl 2.0 API.
- Only FactoryGirl 2.0+ is supported now. If you are using an older version of FactoryGirl, please use factory_girl_extensions < 2.0
- You can no longer use
:email.next
to generate the next :email sequence. factory_girl_extensions no longer includes custom sequence code (because this feature wasn't heavily used and the new FactoryGirl inline sequences are pretty awesome) - The code has been updated to be Ruby 1.8/1.9 compatible and now follows the same patterns as other official FactoryGirl alternative syntaxes
Usage
require 'factory_girl_extensions' # This includes custom methods in every Class. See below to customize this.
FactoryGirl.define do
factory :user do
name 'Bob Smith'
end
end
# Creates a saved instance without raising (same as saving the result of FactoryGirl.build)
User.generate(:name => 'Johnny')
# Creates a saved instance and raises when invalid (same as FactoryGirl.create)
User.generate!
# Creates an unsaved instance (same as FactoryGirl.build)
User.build
# Creates an instance and yields it to the passed block
User.generate do |user|
# ...do something with user...
end
# Creates and returns a Hash of attributes from this factory (same as FactoryGirl.attributes_for).
User.attributes
# A few short aliases are included for convenience.
User.gen
User.gen!
User.attrs
# Factories with custom prefix/suffixes are also supported.
FactoryGirl.define do
factory :admin_user, :parent => :user do
is_admin true
end
factory :user_with_profile, :parent => :user do
profile_complete true
end
factory :admin_user_with_profile, :parent => :admin_user do
profile_complete true
end
end
# Generates the :admin_user factory
User.generate(:admin)
User.generate(:admin, :name => 'Cool Admin')
# Generates the :user_with_profile factory
User.generate(:with_profile)
# Generates the :admin_user_with_profile factory
User.generate(:admin, :with_profile)
User.generate(:admin, :with_profile, :name => 'Custom name')
# User.build and User.attributes also support these custom prefix/suffixes.
# Factories with custom names are supported as well
FactoryGirl.define do
factory :unverified_user, :class => :user do
verified false
end
end
# Generates the :unverified_user factory
User.generate(:unverified)
Extend custom classes with FactoryGirlExtensions
When you require "factory_girl_extensions"
, we include custom methods (build/generate/etc) into
every class by calling:
require "factory_girl_extensions/core"
Class.send :include, FactoryGirlExtensions
If you don't want all of your classes to be polluted with these methods (for example, you only want to extend your ActiveRecord::Base classes with these methods), you can simply:
# don't require factory_girl_extensions! require factory_girl_extensions/core instead.
require "factory_girl_extensions/core"
ActiveRecord::Base.send :extend, FactoryGirlExtensions
Why User.gen instead of FactoryGirl(:user)?
Personally, I really dislike the FactoryGirl(:user)
syntax. When you have a lot of
factories, it's hard to see the names of the actual model classes. I don't like this:
FactoryGirl(:user).should be_valid
FactoryGirl(:name, :string => 'something').should be_awesome
FactoryGirl(:comment, :user => Factory(:user)).should be_cool
FactoryGirl(:user).should do_some_stuff_with(:things)
To me, the thing that draws my attention in that code snippet is FactoryGirl
.
I don't care about Factory
, I care about the actual models! I prefer:
User.gen.should be_valid
Name.gen(:string => 'something').should be_awesome
Comment.gen(:user => User.gen).should be_cool
User.gen.should do_some_stuff_with(:things)
When you syntax highlight the above code, the constants (model names) are usually
the things that really jump out at you. Even in plain text, it's easier to
understand that code than the above FactoryGirl(:code)
in my opinion.
Dude, why isn't this stuff included in the official FactoryGirl gem as an alternative syntax?
Originally, when I made this, not many people were using this syntax.
Now that I know many people using this syntax, I may send a pull request to FactoryGirl to see if they would consider accepting this.
As of factory_girl_extensions 2.0, the code is actually written in the same style as official syntaxes, so it should be very easy to include this into the official FactoryGirl gem.
License
factory_girl_extensions is released under the MIT license.