[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