[rspec-devel] Partially mocked objects that define == blow up when another mock exists

Pat Maddox pergesu at gmail.com
Mon Oct 1 16:11:43 EDT 2007


One of my coworkers wrote a class that defines == to have simple value
object semantics.  One of our specs partially stubs the value object.
A change in the last week or so broke it.  Here's the setup:

stub("existing mock", :foo => :foo)
class ValueObject
  attr_reader :val

  def initialize(val)
    @val = val
  end

  def ==(other)
    @val == other.val
  end
end

@obj = ValueObject.new :bar
@obj.stub!(:some_method)  # blows up with undefined method on
#<Spec::Mocks::Proxy>

Now, this was easily fixed with changing == to

def ==(other)
  other.responds_to?(:val) && @val == val
end

which imo is better anyway, at least in this particular case.  His
argument was, "but we're never going to pass in an object of a
different class" in which case he should probably check the other
object's class just to make sure.

Anyway, I was interested in why this failed, because the error message
wasn't very helpful.

The problem is that in Spec::Mocks::Space#add it calls mocks.include?.
 Internally, Ruby uses == in include?, which in this case blows up.

I've got two ideas on this.  The first is to check for object identity
using equal?.  #add becomes:

def add(obj)
  mocks << obj unless mocks.detect {|m| m.equal? obj}
end

This way people can write the first version of == with no problems.

Another option is to inform them of duck typing, and that they'll want
to either use respond_to or check for the object's class.

The first way is less intrusive, and I think I would prefer it solely
on that merit.  I don't hate the other way though, and that's just as
trivial to implement.  Just rescue NoMethodError in #add with a link
to some duck typing page.

Here's a patch for the .equal? version: http://pastie.caboo.se/102619
I opted not to put it in the tracker because I wanted to generate some
discussion first.  Plus there are a lot of patches that are just
chilling there and I don't know if anyone's looking at them :)

Pat


More information about the rspec-devel mailing list