[mocha-developer] Stubbing yielding methods

James Mead jamesmead44 at gmail.com
Wed Jan 2 10:15:37 EST 2008


On 21/09/2007, Duncan Beevers <duncanbeevers at gmail.com> wrote:
> It's certainly necessary to test the code tucked away into these
> blocks, but I feel like yielding is testing in the wrong direction.
>
> Instead of yielding values or mocks into the block, perhaps we can
> check metadata about the provided block (arity, required params) and
> then test the functionality of the block explicitly.
>
> class Test::Unit::TestCase
>   def test_up_them_all
>     upcasing_block = lambda { |e| e.upcase }
>
>     list_of_words = [ 'socks', 'mittens', 'flashlight' ]
>     list_of_words.expects(:map).with_block(upcasing_block)
>
>     u = Upperizer.new
>     u.up_them_all(list_of_words)
>
>     assert_equal 'HONK', upcasing_block('honk')
>   end
> end
>
>
> On 9/21/07, James Mead <jamesmead44 at gmail.com> wrote:
> > I've just been tying my brain in knots looking at bug #8687 (
> > http://rubyforge.org/tracker/index.php?func=detail&aid=8687&group_id=1917&atid=7477
> > ).
> >
> > I've been (1) trying to work out whether there is anything logically wrong
> > with Mocha's existing behaviour and (2) whether Mocha should support the
> > requested functionality.
> >
> > It all centres around the use of the Expectation#yields method. I've put a
> > couple of examples together to try and help me think about it. The first one
> > (http://pastie.caboo.se/99412) is a simplified version of the example in the
> > bug report using a block and stubbing a method that yields to that block.
> >
> > In the second example (http://pastie.caboo.se/99413) I tried to think about
> > how it would work if I converted the block to a method on an object. I
> > slightly ran out of steam on this one when I realised that in this case when
> > I realised Executor#execute wouldn't be called because the implementation of
> > Collaborator#yielding_method is stubbed.
> >
> > This made me wonder if the Expectation#yields method should exist at all! In
> > particular, in the block example, it feels odd because you are going from
> > real code (ClassUnderTest) into mock code (mocked version of Collaborator)
> > and back into real code (the block itself). I wonder if this is really
> > sensible and/or useful.
> >
> > Has anybody got any thoughts?
> >
> > Thanks.
> > --
> > James.
> > http://blog.floehopper.org
> > http://tumble.floehopper.org
> > _______________________________________________
> > mocha-developer mailing list
> > mocha-developer at rubyforge.org
> > http://rubyforge.org/mailman/listinfo/mocha-developer
> >
> _______________________________________________
> mocha-developer mailing list
> mocha-developer at rubyforge.org
> http://rubyforge.org/mailman/listinfo/mocha-developer
>

This is certainly the direction I was starting to think about. I think
the thing that is not clear from your example is where the Upperizer
gets its *real* upcasing_block from. Also is this upcasing_block the
same instance as the one in the local variable in the test?

Do you think it's sufficient to only check the arity of the block? In
which case you wouldn't actually need to supply the upcasing_block in
the with_block clause, you could just specify the block's arity.
Something along the lines of with_block_having_arity(1).

What do you think?
-- 
James.
http://blog.floehopper.org
http://tumble.floehopper.org


More information about the mocha-developer mailing list