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

2009-07-23 Thread Ben Mabey

Marcelo de Moraes Serpa wrote:

Hello list,

>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?
  
Yes, no, and maybe so. :p  I agree with your general understanding that 
"mocks set expectations and stubs are only dummy objects/method calls".  
The fact that rspec using the same machinery to provide stubs and mocks 
is really inconsequential because the deciding factor of what they are 
is how you use them.  You can, IMO, use a "mock" like a stub and a 
"stub" like a mock.. Take this for example:


describe "#some_method" do
 it "delegates to some_obejct" do
   some_object = stub('some object', :some_method => "foo")
   my_object = MyObject.new(some_object)

   my_object.some_method.should == "foo"
 end
end

We are using a stub as a dummy object, and yet our expectation is 
clearing testing the method call.  So is the above a stub or is it 
really a mock?  I would say that it is acting like a mock.  I hope that 
others on the list will correct me if I am wrong making this 
observation/conclusion.   Likewise we could use a mock as a dummy object 
and never set any expectations on it and it would be acting like a 
stub.  Even though stub and mock is the same in RSpec you should still 
use the correct name when using them.



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 ?
  


Spec::Mocks::ExampleMethods are the methods that you can call during the course of a code example.  
So when you say stub("something") the method in Spec::Mocks::ExampleMethods gets called 
and returns you a stub.  Now, that stub object now has it's own #stub method which lives on 
Spec::Mocks::Methods#stub.  That call will stub out the provided method and return value... So 
my_stub.stub(:foo, "bar"), however that is aliased from #stub! which is used most often.  
This is all from memory so I could be wrong but that is the general gist of it.


HTH,
-Ben
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-23 Thread David Chelimsky
On Thu, Jul 23, 2009 at 7:33 PM, David Chelimsky wrote:
> On Thu, Jul 23, 2009 at 6:39 PM, Marcelo de Moraes
> Serpa 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@rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-23 Thread David Chelimsky
On Thu, Jul 23, 2009 at 6:39 PM, Marcelo de Moraes
Serpa 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.

Cheers,
David

ps - seu nome pareçe brasileiro - você é?

>
> Thanks in advance,
>
> Marcelo.
> ___
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-23 Thread David Chelimsky
On Jul 23, 7:41 pm, Ben Mabey  wrote:
> Marcelo de Moraes Serpa wrote:> Hello list,
>
> > >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?
>
> Yes, no, and maybe so. :p  I agree with your general understanding that
> "mocks set expectations and stubs are only dummy objects/method calls".  
> The fact that rspec using the same machinery to provide stubs and mocks
> is really inconsequential because the deciding factor of what they are
> is how you use them.  You can, IMO, use a "mock" like a stub and a
> "stub" like a mock.. Take this for example:
>
> describe "#some_method" do
>   it "delegates to some_obejct" do
>     some_object = stub('some object', :some_method => "foo")
>     my_object = MyObject.new(some_object)
>
>     my_object.some_method.should == "foo"
>   end
> end
>
> We are using a stub as a dummy object, and yet our expectation is
> clearing testing the method call.  So is the above a stub or is it
> really a mock?  I would say that it is acting like a mock.  I hope that
> others on the list will correct me if I am wrong making this
> observation/conclusion.   Likewise we could use a mock as a dummy object
> and never set any expectations on it and it would be acting like a
> stub.  Even though stub and mock is the same in RSpec you should still
> use the correct name when using them.
>
> > 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 ?
>
> Spec::Mocks::ExampleMethods are the methods that you can call during the 
> course of a code example.  So when you say stub("something") the method in 
> Spec::Mocks::ExampleMethods gets called and returns you a stub.  Now, that 
> stub object now has it's own #stub method which lives on 
> Spec::Mocks::Methods#stub.  That call will stub out the provided method and 
> return value... So my_stub.stub(:foo, "bar"), however that is aliased from 
> #stub! which is used most often.  This is all from memory so I could be wrong 
> but that is the general gist of it.
>
> HTH,
> -Ben

Ben and I are secretly the same person.
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-24 Thread Marcelo de Moraes Serpa
Thanks David and Ben for the comprehensive replies! I really appreciate it :)

These wikipedia articles helped me to understand on the more conceptual level:

http://en.wikipedia.org/wiki/Method_stub
http://en.wikipedia.org/wiki/Mock_object

So, if I understand it right -- Stub is for methods and Mocks are for
roles (or, in the technical-level -- objects).

In the context of rSpec/rSpec-Rails, however,  the API makes it
confusing, to be honest. Being able to create a Mock with
Spec::Mocks:Mock with Spec::Mocks::ExampleMethods# confuses me.

The same applies for stub_model() and mock_model(). I know that
mock_model is a convenience method that can be used to create an
object with an API similar to ActiveRecord::Base's. The API says
stub_model is basically the same, but prevents the object from
accessing the database. Ok, but why attaching these concepts to Stub?
Is this the right name to use for this method? (Stub == mock object
that is not allowed to access the database?).

And there's the  Spec::Mocks::Methods#stub method, which is the one
that reflects the concept that "the Stub is a dummy method".

So, in sum, my perception is that rSpec/rSpec-Rails implement all the
functionality needed to implement Mocks and Stubs,  but in a confusing
way. IMHO, the API is not succinct in this aspect -- it does not
communicate a clear distinction between Mocks and Stubs and this makes
it hard for someone new to TDD/BDD to use them in the right way or
decide the best way to use them.

My 0.4 cents of Brazilian Reals.

@David -- yes, I'm Brazilian! You've got a good gut! And I'm glad to
see that you know Portuguese! :)

Marcelo.

On Thu, Jul 23, 2009 at 8:47 PM, David Chelimsky wrote:
> On Jul 23, 7:41 pm, Ben Mabey  wrote:
>> Marcelo de Moraes Serpa wrote:> Hello list,
>>
>> > >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?
>>
>> Yes, no, and maybe so. :p  I agree with your general understanding that
>> "mocks set expectations and stubs are only dummy objects/method calls".
>> The fact that rspec using the same machinery to provide stubs and mocks
>> is really inconsequential because the deciding factor of what they are
>> is how you use them.  You can, IMO, use a "mock" like a stub and a
>> "stub" like a mock.. Take this for example:
>>
>> describe "#some_method" do
>>   it "delegates to some_obejct" do
>>     some_object = stub('some object', :some_method => "foo")
>>     my_object = MyObject.new(some_object)
>>
>>     my_object.some_method.should == "foo"
>>   end
>> end
>>
>> We are using a stub as a dummy object, and yet our expectation is
>> clearing testing the method call.  So is the above a stub or is it
>> really a mock?  I would say that it is acting like a mock.  I hope that
>> others on the list will correct me if I am wrong making this
>> observation/conclusion.   Likewise we could use a mock as a dummy object
>> and never set any expectations on it and it would be acting like a
>> stub.  Even though stub and mock is the same in RSpec you should still
>> use the correct name when using them.
>>
>> > 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 ?
>>
>> Spec::Mocks::ExampleMethods are the methods that you can call during the 
>> course of a code example.  So when you say stub("something") the method in 
>> Spec::Mocks::ExampleMethods gets called and returns you a stub.  Now, that 
>> stub object now has it's own #stub method which lives on 
>> Spec::Mocks::Methods#stub.  That call will stub out the provided method and 
>> return value... So my_stub.stub(:foo, "bar"), however that is aliased from 
>> #stub! which is used most often.  This is all from memory so I could be 
>> wrong but that is the general gist of it.
>>
>> HTH,
>> -Ben
>
> Ben and I are secretly the same person.
> ___
> rspec-users mailing list
> rspec-users@rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-24 Thread Marcelo de Moraes Serpa
>In the context of rSpec/rSpec-Rails, however,  the API makes it
>confusing, to be honest. Being able to create a Mock with
>Spec::Mocks:Mock with Spec::Mocks::ExampleMethods# confuses me.

Ops! In this paragraph I forgot to put the instance method name: It
should read Spec::Mocks::ExampleMethods#stub

Thanks,

Marcelo.

On Fri, Jul 24, 2009 at 11:51 AM, Marcelo de Moraes
Serpa wrote:
> Thanks David and Ben for the comprehensive replies! I really appreciate it :)
>
> These wikipedia articles helped me to understand on the more conceptual level:
>
> http://en.wikipedia.org/wiki/Method_stub
> http://en.wikipedia.org/wiki/Mock_object
>
> So, if I understand it right -- Stub is for methods and Mocks are for
> roles (or, in the technical-level -- objects).
>
> In the context of rSpec/rSpec-Rails, however,  the API makes it
> confusing, to be honest. Being able to create a Mock with
> Spec::Mocks:Mock with Spec::Mocks::ExampleMethods# confuses me.
>
> The same applies for stub_model() and mock_model(). I know that
> mock_model is a convenience method that can be used to create an
> object with an API similar to ActiveRecord::Base's. The API says
> stub_model is basically the same, but prevents the object from
> accessing the database. Ok, but why attaching these concepts to Stub?
> Is this the right name to use for this method? (Stub == mock object
> that is not allowed to access the database?).
>
> And there's the  Spec::Mocks::Methods#stub method, which is the one
> that reflects the concept that "the Stub is a dummy method".
>
> So, in sum, my perception is that rSpec/rSpec-Rails implement all the
> functionality needed to implement Mocks and Stubs,  but in a confusing
> way. IMHO, the API is not succinct in this aspect -- it does not
> communicate a clear distinction between Mocks and Stubs and this makes
> it hard for someone new to TDD/BDD to use them in the right way or
> decide the best way to use them.
>
> My 0.4 cents of Brazilian Reals.
>
> @David -- yes, I'm Brazilian! You've got a good gut! And I'm glad to
> see that you know Portuguese! :)
>
> Marcelo.
>
> On Thu, Jul 23, 2009 at 8:47 PM, David Chelimsky wrote:
>> On Jul 23, 7:41 pm, Ben Mabey  wrote:
>>> Marcelo de Moraes Serpa wrote:> Hello list,
>>>
>>> > >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?
>>>
>>> Yes, no, and maybe so. :p  I agree with your general understanding that
>>> "mocks set expectations and stubs are only dummy objects/method calls".
>>> The fact that rspec using the same machinery to provide stubs and mocks
>>> is really inconsequential because the deciding factor of what they are
>>> is how you use them.  You can, IMO, use a "mock" like a stub and a
>>> "stub" like a mock.. Take this for example:
>>>
>>> describe "#some_method" do
>>>   it "delegates to some_obejct" do
>>>     some_object = stub('some object', :some_method => "foo")
>>>     my_object = MyObject.new(some_object)
>>>
>>>     my_object.some_method.should == "foo"
>>>   end
>>> end
>>>
>>> We are using a stub as a dummy object, and yet our expectation is
>>> clearing testing the method call.  So is the above a stub or is it
>>> really a mock?  I would say that it is acting like a mock.  I hope that
>>> others on the list will correct me if I am wrong making this
>>> observation/conclusion.   Likewise we could use a mock as a dummy object
>>> and never set any expectations on it and it would be acting like a
>>> stub.  Even though stub and mock is the same in RSpec you should still
>>> use the correct name when using them.
>>>
>>> > 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 ?
>>>
>>> Spec::Mocks::ExampleMethods are the methods that you can call during the 
>>> course of a code example.  So when you say stub("something") the method in 
>>> Spec::Mocks::ExampleMethods gets called and returns you a stub.  Now, that 
>>> stub object now has it's own #stub method which lives on 
>>> Spec::Mocks::Methods#stub.  That call will stub out the provided method and 
>>> return value... So my_stub.stub(:foo, "bar"), however that is aliased from 
>>> #stub! which is used most often.  This is all from memory so I could be 
>>> wrong but that is the general gist of it.
>>>
>>> HTH,
>>> -Ben
>>
>> Ben and I are secretly the same person.
>> ___
>> rspec-users mailing list
>> rspec-users@rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/

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

2009-07-24 Thread Ben Mabey

Marcelo de Moraes Serpa wrote:

Thanks David and Ben for the comprehensive replies! I really appreciate it :)

These wikipedia articles helped me to understand on the more conceptual level:

http://en.wikipedia.org/wiki/Method_stub
http://en.wikipedia.org/wiki/Mock_object

So, if I understand it right -- Stub is for methods and Mocks are for
roles (or, in the technical-level -- objects).

In the context of rSpec/rSpec-Rails, however,  the API makes it
confusing, to be honest. Being able to create a Mock with
Spec::Mocks:Mock with Spec::Mocks::ExampleMethods# confuses me.
  
Hmm.. I can see your point as far as where the methods live being 
confusing.  Reading about stub method in the RDoc pages for mock methods 
does seem odd.  The reason, as David, pointed out is really more due to 
reducing code duplication between the two.  Any suggestions on making it 
better?




The same applies for stub_model() and mock_model(). I know that
mock_model is a convenience method that can be used to create an
object with an API similar to ActiveRecord::Base's. The API says
stub_model is basically the same, but prevents the object from
accessing the database. Ok, but why attaching these concepts to Stub?
Is this the right name to use for this method? (Stub == mock object
that is not allowed to access the database?).
  
I think you raise a good question whether or not stub_model is a best 
name for the functionality it provides.  I think stub_model is really 
called a partial stub.. or partial mock.  Hmm.. I'm not quite sure what 
the correct name is.  But basically, as you said, it is the real object 
but is not allowed to touch the DB.  So it is there for performance 
reasons mostly.  mock_model however gives you a dummy object with some 
predefined stubbed methods that you typically want for an AR object 
(i.e. #id).  However, it is very true that in many cases you will be 
using this "mock_model" as a stub.  I can see how having stub_model can 
cause confusion...


Perhaps, a better API would be to alias stub_model to mock_model (this 
would be more aligned with the #mock and #stub API) and then have a 
partial_stub_model or stub_model(Model, :partial => true)?   Changing it 
now I'm sure would make some people upset but it could be done with 
deprecation warnings if it is causing that much confusion... This would 
really be David's call to make and I'm guessing he had some good reasons 
for making the decision he did in the first place.



And there's the  Spec::Mocks::Methods#stub method, which is the one
that reflects the concept that "the Stub is a dummy method".
  


Again, this is due to the implementation..  I see your point, but I 
don't know if the typical user really cares where it lives.  Perhaps a 
little explanation in the RDoc would be sufficient to avoid confusion?


-Ben
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-24 Thread Rick DeNatale
On Thu, Jul 23, 2009 at 8:41 PM, Ben Mabey wrote:
> You can, IMO, use a "mock" like a stub and a "stub" like a
> mock.. Take this for example:
>
> describe "#some_method" do
>  it "delegates to some_obejct" do
>   some_object = stub('some object', :some_method => "foo")
>   my_object = MyObject.new(some_object)
>
>   my_object.some_method.should == "foo"
>  end
> end
>
> We are using a stub as a dummy object, and yet our expectation is clearing
> testing the method call.  So is the above a stub or is it really a mock?  I
> would say that it is acting like a mock.  I hope that others on the list
> will correct me if I am wrong making this observation/conclusion.

Well, I'm not sure.

There's a difference here.

The stub simply sets things up so that IF some_object receives
:some_method it will return 'foo' instead of something else (including
a method_missing error).

If the implementation looks like:

class MyObject
def initialize(obj)
end

def some_method
   "foo"
end
end

Then the stub object proves nothing, the example will succeed whether
it's there or not.

On the other hand using a mock and setting a message expectation
asserts something about the implementation of some_method and it's
relationship to the intialize method.  It's more gray-box than
black-box.
-- 
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users


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

2009-07-24 Thread Ben Mabey

Rick DeNatale wrote:

On Thu, Jul 23, 2009 at 8:41 PM, Ben Mabey wrote:
  

You can, IMO, use a "mock" like a stub and a "stub" like a
mock.. Take this for example:

describe "#some_method" do
 it "delegates to some_obejct" do
  some_object = stub('some object', :some_method => "foo")
  my_object = MyObject.new(some_object)

  my_object.some_method.should == "foo"
 end
end

We are using a stub as a dummy object, and yet our expectation is clearing
testing the method call.  So is the above a stub or is it really a mock?  I
would say that it is acting like a mock.  I hope that others on the list
will correct me if I am wrong making this observation/conclusion.



Well, I'm not sure.

There's a difference here.

The stub simply sets things up so that IF some_object receives
:some_method it will return 'foo' instead of something else (including
a method_missing error).

If the implementation looks like:

class MyObject
def initialize(obj)
end

def some_method
   "foo"
end
end

Then the stub object proves nothing, the example will succeed whether
it's there or not.

On the other hand using a mock and setting a message expectation
asserts something about the implementation of some_method and it's
relationship to the intialize method.  It's more gray-box than
black-box.
  


True, but I think the difference is very small in this case.  In the 
delegation example we want to ensure that the other method is called and 
that it's return value is returned.  Adjusting your implementation 
slightly you could still make the message expectation version pass as 
well but still be a false-positive:


class MyObject
   def initialize(obj)
   end

   def some_method
some_object.some_method
  "foo"
   end
end


In both cases another example would be needed to point out the problem- each of which 
would rely on returning another canned response.  Of course, using triangulation for 
something small as delegation is just plain silly. :)  FWIW, I would set a message 
expectation when specifying delegation.  However, to my point if a stub is being used in 
this manner I think it is crossing the line of being a dummy object and taking on more of 
a "mock"ish like role.  Perhaps it is going overboard to say that it is being 
used as a mock, but the intent feels the same in this case IMO.


-Ben






___
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users