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



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

Reply via email to