views:

1466

answers:

2

I've recently came across different tutorials, where people use both mock and mock_model functions.

In RSpec tutorial for controllers they use the mock_model function, but right in the documentation of RSpec, there is only mock function, but no mock_model

I tried to run some tests myself, and I didn't find any real difference, since everything was ok when I used either of those two functions, so is there any difference at all?

+3  A: 

From: Useful helpers for RSpec mocks

Firstly, mock_model automatically defines unique ids for models, which were created using it. Secondly, it defines methods to_param (returns string representation of the id) and new_record? (returns false).

jengar
+6  A: 

As jenger said mock_model is an extension built for active record:

This is the source in 1.2.6:

     def mock_model(model_class, options_and_stubs = {})
        id = options_and_stubs[:id] || next_id
        options_and_stubs = options_and_stubs.reverse_merge({
          :id => id,
          :to_param => id.to_s,
          :new_record? => false,
          :errors => stub("errors", :count => 0)
        })
        m = mock("#{model_class.name}_#{id}", options_and_stubs)
        m.__send__(:__mock_proxy).instance_eval <<-CODE
          def @target.as_new_record
            self.stub!(:id).and_return nil
            self.stub!(:to_param).and_return nil
            self.stub!(:new_record?).and_return true
            self
          end
          def @target.is_a?(other)
            #{model_class}.ancestors.include?(other)
          end
          def @target.kind_of?(other)
            #{model_class}.ancestors.include?(other)
          end
          def @target.instance_of?(other)
            other == #{model_class}
          end
          def @target.class
            #{model_class}
          end
        CODE
        yield m if block_given?
        m
      end

So its quite a mouthful, but it

  • stubs the id with the next in a sequence
  • stubs to_param
  • stubs new_record? with false
  • stubs errors so it thinks there are no errors

It also extends the model instance with a bunch of stuff.

Sam Saffron