Invoking the original method on original object after expectation matching?

3,231 views
Skip to first unread message

spilled_coffee

unread,
Oct 16, 2012, 7:53:23 PM10/16/12
to mocha-d...@googlegroups.com
Hi,

The Expectation.returns method only returns fix values:

  # the unit test tests this outer process method
  def outer_process
     list. each { interesting_method(*args) }
     do_something_else_based_on_side_effects_or_raise
  end

  # expecting it be called exactly
  def interesting_method(*args)
     update_side_effects(*args)
     return_value
  end

  # the test codes
   my_obj.expects(:my_method).times(2).returns([100, 200])
   my_obj.outer_process # test it

The problem is that the mocked method will not do anything the original method do. In fact, outer_process may fail just because of that. It would be nice to be able to say something

   my_obj.expects(:my_method).times(2).invoke_original
   my_obj.outer_process # test it

Then for the first two calls, the expectation will maintain the counter and then still call the original method. Any extra calls will raise exception.

I scoped around and don't find any way. Even simple monkey patching Mocha does not seem work, one would have to make deep patch. Is there better way?

Thanks

spilled_coffee

unread,
Oct 18, 2012, 12:49:09 PM10/18/12
to mocha-d...@googlegroups.com
Correction to typo, by

  my_obj.expects(:my_method).times(2).invoke_original

I meant

  my_obj.expects(:interesting_method).times(2).invoke_original

as defined in the example.

Same for the call returning fix values.

Thanks

floehopper

unread,
Oct 19, 2012, 6:25:28 AM10/19/12
to mocha-developer
I find that having a stub sometimes execute it's original
implementation but other times return a stubbed value ends makes tests
very confusing to follow. If I find myself wanting to do this, I tend
to step back from my code a bit and see whether I can re-design the
way it works to make it easier to test.

So Mocha doesn't support the functionality you describe and I doubt it
ever will. I would consider implementing something along the lines of
jMock's Custom Actions [1], but I'm not sure whether this would help
in the case you describe.

Regards, James.
---
http://jamesmead.org
http://gofreerange.com

[1] http://www.jmock.org/custom-actions.html

Duncan Beevers

unread,
Oct 19, 2012, 8:39:04 AM10/19/12
to mocha-d...@googlegroups.com
There are a couple of camps regarding this, and I tend to fall into
the same camp as James on this, reliance on side-effects is kind of a
code smell.

However, we live in an imperfect world, and sometimes we need tools
that do these things, even if they're not best practices.

One approach to this is to use test spies. Although I haven't used it
myself, Thoughbot has released the Bourne library that integrates with
Mocha and provides test spies.

In some spies implementations, messages flow through the spy to the
original receiver, allowing you to check expectations against the spy
while still getting all your nice side-effects. I don't know whether
Bourne operates this way, or if it simply provides an alternative
interface to Mocha's existing mocks expectations.

https://github.com/thoughtbot/bourne

Anyway, best of luck, hope this helps.

Duncan
> --
> You received this message because you are subscribed to the Google Groups "mocha-developer" group.
> To post to this group, send email to mocha-d...@googlegroups.com.
> To unsubscribe from this group, send email to mocha-develop...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/mocha-developer?hl=en.
>
Reply all
Reply to author
Forward
0 new messages