Module ModelFactory::Legacy

  1. lib/modelfactory/legacy.rb

ModelFactory Legacy API

Put something like this in your test helper:

require 'model_factory'

module Factory
  extend ModelFactory

  # a default block accepts a class and a hash of default values
  default Color, {
    :name => 'chartreuse'
  }

  default User, {
    :first_name => 'Harry',
    :last_name => 'Manchester',
    :favorite_color => default_color
  }

  # Add class methods to create whatever kind of objects you need for your tests
  def self.new_user_with_colorblindness
    new_user { :favorite_color => nil }
  end

end

Then in your tests you use Factory methods to instantiate your test objects:

# For most functional tests you can use create.
def test_something
  user = Factory.create_user
  user.friends << Factory.create_user(:first_name => 'Frank')
  assert user.likes_frank?
end

# For unit tests you use new.
def test_something_else
  user = Factory.new_user(:favorite_color => Factory.new_color(:name => 'blue'))
  assert user.likes_blue?
end

# Assertions should not depend on default data, but it can be useful to create
# factory methods that build objects with specific traits.
def test_yet_something_else
  user = Factory.new_user_with_colorblindness
  assert !user.likes_blue?
end

You can also specify types of models in your calls to defaults, but be careful. This can easily start to become a lot like fixtures:

module Factory
  extend ModelFactory

  default User, :joined {
    :first_name => 'Harry',
    :last_name => 'Manchester',
    :joined => true,
    :set_password => true,
  }

  default User, :unjoined {
    :first_name => 'Harry',
    :last_name => 'Manchester',
    :joined => false,
    :set_password => false,
  }
end

Then in your test:

def test_something
  user1 = Factory.create_joined_user(:first_name => 'Bill')
  user2 = Factory.create_unjoined_user(:first_name => 'Sandy')
  assert  user1.joined?
  assert !user2.joined?
end

Methods

public instance

  1. default
  2. method_missing

Public instance methods

default (class_type, *default_args)

When specifying defaults, you should only provide only enough data that the created instance is valid. If you want to include another factory object as a dependency use the special method default_* instead of create_* or new_*.

[show source]
# File lib/modelfactory/legacy.rb, line 93
    def default(class_type, *default_args)
      defaults   = default_args.pop || {}
      prefix     = default_args.first
      class_name = class_type.name.demodulize.underscore
      class_name = "#{prefix}_#{class_name}" if prefix

      (class << self; self; end).module_eval do
        define_method "create_#{class_name}" do |*args|
          attributes = args.first || {}
          create_instance(class_type, attributes, defaults)
        end
      
        define_method "new_#{class_name}" do |*args|
          attributes = args.first || {}
          new_instance(class_type, attributes, defaults)
        end

        define_method "default_#{class_name}" do |*args|
          attributes = args.first || {}
          default_closure(class_type, attributes, defaults)
        end
      end
    end
method_missing (missing_method, attributes = {})

Any class methods of the form “new_some_type(attrs)” or “create_some_type(attrs)” will be converted to “SomeType.new(attrs)“ and “SomeType.create!(attrs)“ respectively. These basically function as though you’d used the ‘default’ directive with empty defaults.

[show source]
# File lib/modelfactory/legacy.rb, line 174
    def method_missing(missing_method, attributes = {})
      if missing_method.to_s.match(/^(new|create|default)_([a-z][\w_]+)$/)
        method, class_name = $1, $2
        class_type = class_name.camelize.constantize
        case method
        when 'create'
          create_instance(class_type, attributes)
        when 'new'
          new_instance(class_type, attributes)
        when 'default'
          default_closure(class_type, attributes)
        end
      else
        raise NoMethodError, "no such method '#{missing_method}'"
      end
    end