[mocha-developer] mocking missing methods

Dan North dan at tastapod.com
Mon Apr 30 18:21:37 EDT 2007

This is timely for me. I've been thinking about exactly this vocabulary 
recently, but in the context of BDD rather than (as well as?) mocking. 
It's about the terms "is a" and "has a" and how they restrict your 
thinking because they don't really cover the idea of roles. You need 
"acts like a" or "behaves like a" to really describe multiple hats.

In this instance, I would like something like "acts like a" (in fact, 
David and I were discussing "quacks_like" in another conversation).

Here's some thinking-out-loud:


This should be additive:
or even:
    mock_ninja_sheep.acts_like(Sheep.new, Ninja.new)

One problem I see is a hard-to-detect semantic error:
    mock_sheep.acts_like(Sheep) # oops - meant Sheep.new

Also, what about modules? This is fugly:
    mock_countable_sheep.acts_like(Sheep.new.extend(Enumerable)) # yuk

So, we need a way of saying: "fail intuitively if the mocked object 
wouldn't respond to this call".

Ok, end of ramble. Here's my ill-thought-out proposal:

mock_sheep = mock("sheep")                    # give it a name
mock_sheep.responds_like_type(Sheep, ...)     # uses #instance_method
mock_sheep.responds_like_instance(ninja, ...) # uses #respond_to?
mock_sheep.responds_like(cheese)              # depends if cheese is 

The responds_like_type version could even check if type implements 

The failure mode here would be if you wanted to mock the /instance/ 
methods of a /class/, using responds_like(type), but that seems very 
much like an edge case, and you could explicitly use 
responds_like_instance(type) anyway.

Of course, all these checks would be done at method invocation time, so 
late binding would work.


David Chelimsky wrote:
> On 4/27/07, Jay Fields <jay at jayfields.com> wrote:
>>> In the case of just Sheep, it
>>> could ask for it's public_class_methods. In the case of
>>> instance_of(Sheep) it would have to ask for something else - or you'd
>>> have to override public_class_methods on the object returned by
>>> instance_of(Sheep) to return the sheep's public_instance_methods -
>>> which just doesn't seem right to me.
>> How about:
>> # instance methods
>> sheep = mock
>> sheep.restricted_to Sheep.instance_methods
>> or
>> # class methods
>> sheep = mock
>> sheep.restricted_to Sheep.singleton_methods
>> It's a bit more verbose, but more readable in my opinion.  Also, I'm
>> not sold on responds_to or restricted_to.  I don't find that either
>> one conveys the intent I'm looking for.
>> Thoughts?
> I love the syntax, though I'd make it a command rather than a "state"-ment:
> # instance methods
> sheep = mock
> sheep.restrict_to Sheep.instance_methods
> # class methods
> sheep = mock
> sheep.restrict_to Sheep.singleton_methods
> The other problem is related to Dan's initial point about classes that
> are extended or modified at runtime. If you just pass an Array to
> #restrict_to then it has no knowledge of the type we're interested in,
> so methods added downstream wouldn't be discoverable. With that in
> mind, I propose:
> # instance methods
> sheep = mock
> sheep.restrict_to Sheep, :instance_methods
> # class methods
> sheep = mock
> sheep.restrict_to Sheep, :singleton_methods
> That keeps the readability Jay proposes and supports the late binding
> we're looking for.
> More thoughts?
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer

More information about the mocha-developer mailing list