[mocha-developer] Terse Mocks

Dan North dan at tastapod.com
Wed May 2 13:25:52 EDT 2007


+1 to both parts of the original post.

I implemented this in my own mocking framework (everyone should write a 
mocking framework - it's fun!) using a similar syntax, like this:

mock_sheep = mock(Sheep) # see earlier thread

mock_sheep.expects do |m|
    m.chew_grass           # method call
    m.say("baa")           # method with params
    m.jump(kind_of(Hedge)) # matchers in mocks
    m.ask_time.returns("3 o'clock")      # return values
    m.shoot.raises(DeceasedSheepError, "ouch")  # exceptions
end

It's easier on the eye than :labels_for_methods. Likewise, you can stub 
the same way, just with stub{|m| ...} instead of expect{|m| ...}:

mock_sheep.stubs { |m|
    m.dont_care_about_this
    m.this_might_get_called.returns("Tuesday")
}

It's easy to implement by temporarily replacing method_missing in the 
mock and then passing it into the block. I found it led to nicely 
readable mock interactions, and it's a useful alternative syntax.

Cheers,
Dan

ps. You're welcome to the original code if you think it might help. It's 
not very clever though ;)


James Mead wrote:
> On 02/05/07, Brian Takita <brian.takita at gmail.com> wrote:
>   
>> I recently made a feature request with a patch for terser mocks.
>>
>> http://rubyforge.org/tracker/index.php?func=detail&aid=10412&group_id=1917&atid=7480
>>     
>
>
> Thanks for the feature request and especially for going to the trouble of
> writing a patch.
> I'm sorry for not responding - I've been busy with as usual.
>
> Here are some examples with their current equivalents:
>   
>> the_mock.expects.foo(1,2) {|a, b| :bar}
>> the_mock.expects.foo(1,2).returns(:bar)
>> the_mock.expects(:foo).with(1,2) {|a, b| :bar}
>> the_mock.expects(:foo).with(1,2).returns(:bar)
>>     
>
>
> Hmm. I quite like the syntax of the first half, e.g.
> "the_mock.expects.foo(1,2)", because it's similar to how the expected method
> would be called. But I'm not so keen on the block syntax for the return
> value, e.g. "{|a, b| :bar}", because I don't think it's as readable.
>
> The patch is pretty simple too.
>
>
> Sorry, I haven't had a chance to look at the code in the patch yet.
>
> Also, here is an example from my feature request for mock blocks that does
>   
>> not have a patch yet.
>>
>> http://rubyforge.org/tracker/index.php?func=detail&aid=10413&group_id=1917&atid=7480
>>
>> the_mock = mock('The new mock') do
>>   foo(1,2) {:bar}
>>   baz(3,4).returns(:foobar)
>> end
>>
>> In the previous block, expectations for foo and baz are being set.
>> This block is equivalent to:
>>
>> the_mock = mock('The new mock')
>> the_mock.expects(:foo).with(1,2) {:bar}
>> the_mock.expects(:baz).with(3,4).returns(:foobar)
>>     
>
>
> I've been thinking of doing something similar, but I would like to retain
> the clear distinction between expecting and stubbing...
>
> larry = mock() do
>   named('Larry')
>   responds_like(Lamb.new)
>   expects(:baa)
>   stubs(:meh)
> end
>
> Here is an ActiveRecord type example of the mock block syntax:
>   
>> User.mocks do
>>   find('3').once {user}
>>   destroy(7)
>> end
>>
>> I don't think this would be too difficult to implement either.
>>
>> WDYT?
>>
>>     
>
> Thanks for your suggestions. What does anybody else think?
>
>   



More information about the mocha-developer mailing list