[rspec-users] On Mocks vs Stubs in the context of rSpec

David Chelimsky dchelimsky at gmail.com
Thu Jul 23 20:41:18 EDT 2009


On Thu, Jul 23, 2009 at 7:33 PM, David Chelimsky<dchelimsky at gmail.com> wrote:
> On Thu, Jul 23, 2009 at 6:39 PM, Marcelo de Moraes
> Serpa<celoserpa at gmail.com> wrote:
>> Hello list,
>
> Oi Marcelo,
>
>>
>> >From what I could see, the lines between mocks and stubs are subtle,
>> but the general idea I got is that mocks set expectations and stubs
>> are only dummy objects/method calls. What confused me though, is that
>> the stub() method is an alias for mock() in
>> Spec::Mocks::ExampleMethods. So a stub is a mock?
>
> The conversation about stubs and mocks are usually about Mock Objects
> and Test Stubs - i.e. two theoretically different kinds of objects.
> The functional difference between them, however, is really at the
> _method_ level, and even then, they are mostly the same:
>
> Both Method Stubs (stub()) and Method Expectations (should_receive()):
> * respond to a call
> * can return a canned value
> * can return different values to subsequent calls
> * can raise errors
> * can yield values to a block
> * etc, etc, etc
>
> Only Method Expectations can verify that they have been received. That
> is the primary difference between them.
>
> Keep in mind that these ideas evolved and appeared at different times
> and as different things, but over time have evolved to nearly the same
> thing with the exception of verification.
>
> The primary benefit we get from verification is when we care about a
> specific interaction that causes a side effect that we can not
> perceive from the object we're dealing with. Let's say we want to spec
> that an object logs something in response to a message given specific
> conditions:
>
> describe Account do
>  it "logs a message when it is queried for its balance" do
>    logger = mock('logger')
>    logger.should_receive(:log).with(/queried for balance on/)
>    account = Account.new(logger)
>    account.balance
>  end
> end
>
> Note that this spec never expects any values on the account itself.
> This is the classic example of the use of a mock object, or more
> accurately (in my opinion) a message expectation.
>
> Now in cases like we see so often in Rails controller specs, in my
> view there is little difference between these two:
>
> describe ThingController do
>  describe "GET index" do
>    it "assigns all things as @things (using a message expectation)" do
>      thing = stub_model(Thing)
>      Thing.should_receive(:all).and_return([thing])
>      get :index
>      assigns[:things].should == [thing]
>    end
>
>    it "assigns all things as @things (using a stub)" do
>      thing = stub_model(Thing)
>      Thing.stub(:all).and_return([thing])
>      get :index
>      assigns[:things].should == [thing]
>    end
>  end
> end
>
> In this case, the implicit verification in the first example doesn't
> buy us all that much, so the second example does a perfectly good job
> and is slightly less brittle.
>
>> Also, another thing that is confusing: You have stub and stub! methods
>> in the Spec::Mocks::Methods namespace, what is the difference between
>> Spec::Mocks::ExampleMethods#stub and Spec::Mocks::Methods#stub ?
>
> The original method was stub!, which I will confess to introducing,
> and for the wrong reasons, due to my misunderstanding of the meaning
> of ! in ruby methods.
>
> I recently added stub (with no !) with no particular fanfare, as I
> don't intend to remove stub! (at least not any time soon). Right now
> the docs don't make it clear, so I need to fix that - but I'd say that
> stub() is the method to use and stub!() is there for backwards
> compatibility.

I misread your question :)

Here's the answer you're looking for: the diff between
Spec::Mocks::ExampleMethods#stub and Spec::Mocks::Methods#stub:

Spec::Mocks::ExampleMethods#stub creates an instance of
Spec::Mocks::Mock :) Oh the irony. So does
Spec::Mocks::ExampleMethods#mock.

Spec::Mocks::Methods#stub (and Spec::Mocks::Methods#stub!) creates a
method stub on self.

HTH,
David

>
> Cheers,
> David
>
> ps - seu nome pareçe brasileiro - você é?
>
>>
>> Thanks in advance,
>>
>> Marcelo.
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>


More information about the rspec-users mailing list