[rspec-devel] [ rspec-Patches-14362 ] [PATCH] partially mocking objects that define == can blow up

noreply at rubyforge.org noreply at rubyforge.org
Mon Oct 1 19:49:17 EDT 2007


Patches item #14362, was opened at 2007-10-01 17:49
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3151&aid=14362&group_id=797

Category: None
Group: None
Status: Open
Resolution: None
Priority: 3
Submitted By: Pat Maddox (pergesu)
Assigned to: Nobody (None)
Summary: [PATCH] partially mocking objects that define == can blow up

Initial Comment:
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

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=3151&aid=14362&group_id=797


More information about the rspec-devel mailing list