[rspec-users] message expectations without explicit receiver

Matt Wynne matt at mattwynne.net
Fri Apr 10 16:40:08 EDT 2009


On 10 Apr 2009, at 19:43, Barun Singh wrote:

> A model I'm trying to spec looks something like this
>
> class MyClass
>   def methodA
>     do some stuff
>     methodB
>   end
>
>   def methodB
>     do some stuff
>   end
> end
>
> my spec looks something like this:
>
> x = MyClass.new
> x.should_receive(:methodB)
> lambda{ x.methodA }
>
> In the situation outlined above, the spec fails.  But, if I change  
> the definition of methodA to be as follows the spec passes (note the  
> addition of "self" as the receiver):
>
> def methodA
>   do some stuff
>   self.methodB
> end
>
>
> The code doesn't actually need for me to identify "self" as the  
> receiver on order for it to work.  But rSpec seems to require this.   
> Is there an alternative way to write the spec so that it passes in  
> the original case (where I call methodB without an explicit receiver)?

You're going into some pretty messy territory here, trying to insert a  
mocking layer between two methods of the same class. Since most people  
who use RSpec wouldn't want to do this, you've found that's it not  
possible. I also suspect it would be quite difficult to write the  
mocking code, but that's a different issue.

I could write more about this, and I suspect others will, but for now  
I would suggest that you listen to your test and try to test the  
behaviour of the whole class, only mocking out collaborating objects.  
This will ensure there's as little coupling as possible between the  
tests and the code, making that code easier to change. Here are a  
couple of things you could read up to see what I mean:

http://www.jmock.org/oopsla2004.pdf
http://www.patmaddox.com/blog/2008/10/27/testing-protected-and-private-methods-in-ruby

Matt Wynne
http://beta.songkick.com
http://blog.mattwynne.net





More information about the rspec-users mailing list