Topic: mocks vs stubs for beginner :: rspec examples

Please excuse me, for this has been here before (probably, many times) but I've honestly read everything relevant in google (including Martin Fowler) and here and still I have no deep enough understanding of the subject.

What I want here is simple, but well-grounded explanation of the difference between mocks and stubs and real examples when these two approaches can't substitute each other.

The way I see the difference between those two:

saved_photo = mock(Img)
saved_img.should_receive(:update_attributes).and_return true

and
 Img.stub!(:update_attributes).and_return true

is that the first one fakes an instance method, while the second one fakes a class method.
Am I wrong? What is the real difference?

Re: mocks vs stubs for beginner :: rspec examples

check out the sample controller at http://rspec.info/documentation/rails/w … lers.html. It helped me figure out when and how to use stubs and mocks. The part you are looking for is probably...

describe PeopleController do
  # If you pass the controller to #describe, you don't need to declare the controller name

  before(:each) do
    @person = mock("person")

    # Generally, prefer stub! over should_receive in setup.
    @person.stub!(:new_record?).and_return(false)
    Person.stub!(:new).and_return(@person)
  end

  it "should create a new, unsaved person on GET to create" do
    # Using should_receive here overrides the stub in setup. Even
    # though it is the same as the stub, using should_receive sets
    # an expectation that  will be verified. It also helps to
    # better express the intent of this example.
    Person.should_receive(:new).and_return(@person)
    get 'create'
  end
...
end

Re: mocks vs stubs for beginner :: rspec examples

The best explanation I've found that really clarified it for me was from a video I found at the railsenvy site.

* Stub - method with canned response
* Mock - object with canned response

Here's a link to the video

Re: mocks vs stubs for beginner :: rspec examples

a stub is a fake object or method.

a mock is stub with a testing expectation.  (Ie. if the conditions are not met in the test, the mock will chalk up a testing failure-- ie. the number of failures will increase by one.)  a stub doesn't have that behavior.  there are no expectations in a stub.

Example, in RSpec

x = X.find(1)
x.stub!(:greet).and_returns("hello")

Now if you say

x.greet
=> "hello"

Re: mocks vs stubs for beginner :: rspec examples

@dbit_solutions:
A stub is a fake method, but a mock is a fake object. You might create a mock object for an ActiveRecord model, and then stub out many of its methods (like find or greet), having them return a pre-determined response. In your example below, you could stub out the find method to return a mock instance of the X class.

In your example, the find method of the X class will do a find on your test database. Unless you want to actually use the data in your test database, you could just say x = mock_model(X, :greet => 'hello'), which creates a mock instance of the X class and stubs out its 'greet' method to return 'hello'. The mock_model method takes two arguments: the first is the class name of which you want a mock instance, and the second argument is a hash of methods you want to stub, with the method names as their keys and the "canned response" as their value.

It is also important to understand that a mock does not come with any expectations. Mocks and stubs are used mostly in controller specs. You really have to focus in on exactly what it is you're specing. In a controller spec, we don't care about how our data objects are created or what data they contain; we are writing expectations for the functional behavior of that controller, and that controller only. Mocks and stubs are used to decouple from the model layer and stay focused on the task of specing the controller. Hopefully this helped clarify the difference between the two.

Re: mocks vs stubs for beginner :: rspec examples

# from http://rspec.info/rdoc the short version:

Mocks are objects that allow you to set and verify expectations that they will receive specific messages during run time. They are very useful for specifying how the subject of the spec interacts with its collaborators. This approach is widely known as "interaction testing".

Mocks are also very powerful as a design tool. As you are driving the implementation of a given class, Mocks provide an anonymous collaborator that can change in behaviour as quickly as you can write an expectation in your spec. This flexibility allows you to design the interface of a collaborator that often does not yet exist. As the shape of the class being specified becomes more clear, so do the requirements for its collaborators - often leading to the discovery of new types that are needed in your system.

Stubs are objects that allow you to set "stub" responses to messages. As Martin Fowler points out on his site, mocks_arent_stubs. Paraphrasing Fowler