def mock_model(string_or_model_class, stubs = {})
      if String === string_or_model_class
        if Object.const_defined?(string_or_model_class)
          model_class = Object.const_get(string_or_model_class)
        else
          model_class = Object.const_set(string_or_model_class, Class.new do
            extend ::ActiveModel::Naming
            def self.primary_key; :id; end
          end)
        end
      else
        model_class = string_or_model_class
      end

      unless model_class.kind_of? ::ActiveModel::Naming
        raise ArgumentError.new <<-EOM
The mock_model method can only accept as its first argument:
* A String representing a Class that does not exist
* A String representing a Class that extends ActiveModel::Naming
* A Class that extends ActiveModel::Naming

It received #{model_class.inspect}
EOM
      end

      stubs = {:id => next_id}.merge(stubs)
      stubs = {:persisted? => !!stubs[:id],
               :destroyed? => false,
               :marked_for_destruction? => false,
               :valid? => true,
               :blank? => false}.merge(stubs)

      double("#{model_class.name}_#{stubs[:id]}", stubs).tap do |m|
        msingleton = class << m; self; end
        msingleton.class_eval do
          include ActiveModelInstanceMethods
          include ActiveRecordInstanceMethods if defined?(ActiveRecord)
          include ActiveModel::Conversion
          include ActiveModel::Validations
        end
        if defined?(ActiveRecord)
          [:save, :update_attributes, :update].each do |key|
            if stubs[key] == false
              RSpec::Mocks.allow_message(m.errors, :empty?).and_return(false)
            end
          end
        end

        msingleton.__send__(:define_method, :is_a?) do |other|
          model_class.ancestors.include?(other)
        end unless stubs.has_key?(:is_a?)

        msingleton.__send__(:define_method, :kind_of?) do |other|
          model_class.ancestors.include?(other)
        end unless stubs.has_key?(:kind_of?)

        msingleton.__send__(:define_method, :instance_of?) do |other|
          other == model_class
        end unless stubs.has_key?(:instance_of?)

        msingleton.__send__(:define_method, :__model_class_has_column?) do |method_name|
          model_class.respond_to?(:column_names) && model_class.column_names.include?(method_name.to_s)
        end

        msingleton.__send__(:define_method, :has_attribute?) do |attr_name|
          __model_class_has_column?(attr_name)
        end unless stubs.has_key?(:has_attribute?)

        msingleton.__send__(:define_method, :respond_to?) do |method_name, *args|
        include_private = args.first || false
          __model_class_has_column?(method_name) ? true : super(method_name, include_private)
        end unless stubs.has_key?(:respond_to?)

        msingleton.__send__(:define_method, :method_missing) do |m, *a, &b|
          respond_to?(m) ? null_object? ? self : nil : super(m, *a, &b)
        end

        msingleton.__send__(:define_method, :class) do
          model_class
        end unless stubs.has_key?(:class)

        mock_param = to_param
        msingleton.__send__(:define_method, :to_s) do
          "#{model_class.name}_#{mock_param}"
        end unless stubs.has_key?(:to_s)
        yield m if block_given?
      end
    end
def mock_model(string_or_model_class, stubs = {})
      if String === string_or_model_class
        if Object.const_defined?(string_or_model_class)
          model_class = Object.const_get(string_or_model_class)
        else
          model_class = Object.const_set(string_or_model_class, Class.new do
            extend ::ActiveModel::Naming
            def self.primary_key; :id; end
          end)
        end
      else
        model_class = string_or_model_class
      end

      unless model_class.kind_of? ::ActiveModel::Naming
        raise ArgumentError.new <<-EOM
The mock_model method can only accept as its first argument:
* A String representing a Class that does not exist
* A String representing a Class that extends ActiveModel::Naming
* A Class that extends ActiveModel::Naming

It received #{model_class.inspect}
EOM
      end

      stubs = {:id => next_id}.merge(stubs)
      stubs = {:persisted? => !!stubs[:id],
               :destroyed? => false,
               :marked_for_destruction? => false,
               :valid? => true,
               :blank? => false}.merge(stubs)

      double("#{model_class.name}_#{stubs[:id]}", stubs).tap do |m|
        msingleton = class << m; self; end
        msingleton.class_eval do
          include ActiveModelInstanceMethods
          include ActiveRecordInstanceMethods if defined?(ActiveRecord)
          include ActiveModel::Conversion
          include ActiveModel::Validations
        end
        if defined?(ActiveRecord)
          [:save, :update_attributes, :update].each do |key|
            if stubs[key] == false
              RSpec::Mocks.allow_message(m.errors, :empty?).and_return(false)
            end
          end
        end

        msingleton.__send__(:define_method, :is_a?) do |other|
          model_class.ancestors.include?(other)
        end unless stubs.has_key?(:is_a?)

        msingleton.__send__(:define_method, :kind_of?) do |other|
          model_class.ancestors.include?(other)
        end unless stubs.has_key?(:kind_of?)

        msingleton.__send__(:define_method, :instance_of?) do |other|
          other == model_class
        end unless stubs.has_key?(:instance_of?)

        msingleton.__send__(:define_method, :__model_class_has_column?) do |method_name|
          model_class.respond_to?(:column_names) && model_class.column_names.include?(method_name.to_s)
        end

        msingleton.__send__(:define_method, :has_attribute?) do |attr_name|
          __model_class_has_column?(attr_name)
        end unless stubs.has_key?(:has_attribute?)

        msingleton.__send__(:define_method, :respond_to?) do |method_name, *args|
        include_private = args.first || false
          __model_class_has_column?(method_name) ? true : super(method_name, include_private)
        end unless stubs.has_key?(:respond_to?)

        msingleton.__send__(:define_method, :method_missing) do |m, *a, &b|
          respond_to?(m) ? null_object? ? self : nil : super(m, *a, &b)
        end

        msingleton.__send__(:define_method, :class) do
          model_class
        end unless stubs.has_key?(:class)

        mock_param = to_param
        msingleton.__send__(:define_method, :to_s) do
          "#{model_class.name}_#{mock_param}"
        end unless stubs.has_key?(:to_s)
        yield m if block_given?
      end
    end
Creates a test double representing `string_or_model_class` with common
 ActiveModel methods stubbed out. Additional methods may be easily
 stubbed (via add_stubs) if `stubs` is passed. This is most useful for
 impersonating models that don't exist yet.

 ActiveModel methods, plus <tt>new_record?</tt>, are
 stubbed out implicitly.  <tt>new_record?</tt> returns the inverse of
 <tt>persisted?</tt>, and is present only for compatibility with
 extension frameworks that have yet to update themselves to the
 ActiveModel API (which declares <tt>persisted?</tt>, not
 <tt>new_record?</tt>).

 `string_or_model_class` can be any of:

   * A String representing a Class that does not exist
   * A String representing a Class that extends ActiveModel::Naming
   * A Class that extends ActiveModel::Naming