Sequel::Factory implements a tiny DSL on Sequel::Model that allows you to create factories for objects of a model class. A factory is simply a Ruby block that gets evaluated each time a new object is generated. Inside the block you can call methods that correspond to the names of attributes of the object you're creating. If a value is given to the method, it will set the value for that attribute. Regardless, the method will always return the current value for that attribute.
Factories have names (the default name is :default) and you can include a factory in another. When you do this, the included factory will run first.
A simple factory for a User class might look like this:
User.factory do
name "Michael Jackson"
handle name.downcase.gsub(/[^a-z]/, '')
email "#{handle}@example.com"
end
User.factory(:with_avatar) do
include User.factory
avatar_url "http://example.org/#{handle}.jpg"
endYou can now call User.make and it will create an instance of User using the default factory. If you want to generate a User object with all the attributes of a "default" User object plus an avatar, use User.make(:with_avatar).
If you pass a block as the value of an attribute, it acts like a sequence. That is, each time an object is generated the block will be called with a unique, incrementing number. The following factory builds upon the previous example and uses a block to generate a unique value for the twitter_id attribute.
User.factory(:twitter_user) do
include User.factory(:with_avatar)
twitter_id {|n| n }
twitter_handle "@#{handle}"
endNow, when you do a User.make(:twitter_user), that object will have the attributes unique to the :twitter_user factory, plus those of the :with_avatar factory.
Of course, the whole point of factories is to be able to generate different instances each time you run them. Use the Randexp gem for great win here.
By default factories use Sequel::Model.create to create new instances. If you don't want to use it, simply change the model's factory_method. For example, to avoid saving factory-created User objects to the database, you could do:
User.factory_method = :newAnother value that can sometimes be useful here is :find_or_create, e.g. when you're using a factory to create objects that have a unique constraint on some column.