Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between mock and mock_model in RSpec

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?

like image 755
Jakub Arnold Avatar asked Aug 12 '09 01:08

Jakub Arnold


People also ask

What is mocking in RSpec?

Mocking is a technique in test-driven development (TDD) that involves using fake dependent objects or methods in order to write a test. There are a couple of reasons why you may decide to use mock objects: As a replacement for objects that don't exist yet.

What is a mock in Ruby?

Mocks are “smart” stubs, their purpose is to verify that some method was called. They are created with some expectations (expected method calls) and can then be verified to ensure those methods were called.

What is RSpec double?

RSpec features doubles that can be used as 'stand-ins' to mock an object that's being used by another object. Doubles are useful when testing the behaviour and interaction between objects when we don't want to call the real objects - something that can take time and often has dependencies we're not concerned with.

What is Rails RSpec?

RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.


1 Answers

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.

like image 87
Sam Saffron Avatar answered Sep 21 '22 09:09

Sam Saffron