[mocha-developer] Terse Mocks

Brian Takita brian.takita at gmail.com
Wed May 2 18:16:52 EDT 2007


On 5/2/07, James Mead <jamesmead44 at gmail.com> 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 block I provided actually does more than it needs to.
This is what it should have been:
the_mock.expects.foo(1,2) {:bar}

Is the unreadability from the fact that 'returns' is not explicitly stated
or from the fact that there was unneeded code '|a, b|'?

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


>From Dan:

> It's easier on the eye than :labels_for_methods


I think it's easier on the eye because it simulates how the method is
actually used.

I found it led to nicely readable mock interactions, and it's a useful
> alternative syntax.
>
I like that that you found it useful in practice :) A common complaint I've
heard about mocks is that they are less readable than using plain domain
objects.

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 easy to implement by temporarily replacing method_missing in the
> mock and then passing it into the block.
>
You can also have a "Recorder" type object that implements method_missing
and instance eval the block. That way, you can avoid having to pass in the
reference to the mock '|m|'.

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?
>
> --
> James.
> http://blog.floehopper.org
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer
>


More information about the mocha-developer mailing list