[erlang-questions] mockgyver -- yet another mocking library

Jon Watte jwatte@REDACTED
Mon Nov 7 04:19:37 CET 2011


When it comes to mocking, I know that this is one option, and a number of
people are recommending meck. However, both of these use the "sort it all
out afterwards" approach, which I personally feel is not strict enough.
When you mock, you want to mock for a few reasons:
1) You want plausible data to be returned from unrelated modules. You don't
really need to go to a disk mnesia table to test your configuration parser
:-)
2) You want to enforce that, when functions are called, parameters conform
to certain parameters. This may be "is exactly x,z,y" or just "is numeric"
or whatever.
3) You want to enforce the presence or absence of specific calls with
specific parameters.

I find that the "setup" then "replay" mechanism of erlymock (by Jason
Wagner) is almost ideally suited to these cases -- and, once I mocked, and
run my code, the system automatically verifies my expectations; I don't
have to go trawling through any captured results of calls to try to verify
whether they are good or not!
Now, in cases where you want to mock gen_server, or erlang, the code
replacement approach used just won't work. I don't think there's much of a
way around that, other than to use shallow wrappers in your own code, and
mock those wrappers.
Personally, I really wish that module got some more public love in the
Erlang community. To me, it does it close to Right(tm).

Sincerely,

jw


--
Americans might object: there is no way we would sacrifice our living
standards for the benefit of people in the rest of the world. Nevertheless,
whether we get there willingly or not, we shall soon have lower consumption
rates, because our present rates are unsustainable.



On Sun, Nov 6, 2011 at 3:19 AM, Klas Johansson <klas.johansson@REDACTED>wrote:

> Hi Adam,
>
> On Fri, Nov 4, 2011 at 4:54 PM, Adam Lindberg
> <adam.lindberg@REDACTED> wrote:
>
> > Nice to see more mocking tools popping up!
>
> :-)
>
> >  - Is it tied to EUnit or generic?
>
> It's generic (the ?MOCK macro is generic, although the
> ?WITH_MOCKED_SETUP macro is intended for use from eunit).
>
> >  - What happens when a function is called with other parameters than
> those expected?
>
> Nothing.  If I write a "guard" like this:
>
>    ?WAS_CALLED(lists:nth(2, [a, b, c])),
>
> that call will succeed if the function was called with those
> parameters once.  If it was called with those parameters for example
> twice (or never) it'll fail (like an assert macro in eunit).  If it
> was called once with those parameters, and once with another set of
> parameters it still succeeds.
>
> If you want to check that the function was only called once with those
> parameters and no other parameters you can do something like this:
>
>   [[2, [a, b, c]]] = ?WAS_CALLED(lists:nth(_, _)),
>
> since ?WAS_CALLED (as well as ?WAIT_CALLED and ?GET_CALLS) will always
> return a list of argument lists.
>
> Not as concise.  Perhaps a better syntax for those cases will make it
> into a future version. :-)
>
> >  - How's the beam renaming working out for you so far? Have you seen any
> cases in
> >   where it hasn't been able to find all occurrences of a module name?
>
> So far it's done its job, but it's not really bullet proof.  Haven't
> had the need to call the original module frequently enough to bump
> into problems.  The algorithm only replaces the atom within the atom
> table, but not within the constant pool.  mockgyver works for modules
> both with and without debug_info, but I've been thinking of changing
> that:
>
> * use debug_info when available
> * otherwise, resort to replacing within the beam code
>
> It's not been an issue so far, but if people start using this and bump
> into problems I'll prioritize it.
>
> >  - really nice syntax (thanks to parse transforms).
>
> Thanks!
>
> > Is there a functional API?
>
> Yes and no.  There is, but it's not documented and may change.
> However, nothing is set in stone. If there are good reasons for adding
> such an interface it'll be done.
>
> Cheers,
> Klas
>
> > On 2011-11-02, at 21:47 , Klas Johansson wrote:
> >
> >> Hi all,
> >>
> >> I'd like you to meet mockgyver -- an Erlang tool which will make it
> >> easier to write EUnit tests that need to replace or alter (stub/mock)
> >> the behaviour of other modules.
> >>
> >> mockgyver aims to make that process as easy as possible with a
> >> readable and concise syntax.
> >>
> >> mockgyver is built around two main constructs: ?WHEN which makes it
> >> possible to alter the behaviour of a function and another set of
> >> macros (like ?WAS_CALLED) which check that a function was called with
> >> a chosen set of arguments.  Let's redefine pi to 4:
> >>
> >>       ?WHEN(math:pi() -> 4),
> >>       4 = math:pi(),
> >>
> >> Use pattern matching to check that a function was called with certain
> arguments:
> >>
> >>       ?WAS_CALLED(lists:reverse([a, b, c])),
> >>
> >> ... or if you don't care about the arguments:
> >>
> >>       ?WAS_CALLED(lists:reverse(_)),
> >>
> >> The library has been in use for a year for a bunch of Erlang
> >> applications, except for a couple of recent additions.
> >>
> >> A short tutorial as well as docs and many more examples[1] in markdown
> >> format on github:
> >>
> >>    https://github.com/klajo/mockgyver
> >>
> >>
> >> Cheers,
> >> Klas
> >>
> >> [1] https://github.com/klajo/mockgyver/blob/master/doc/mockgyver.md
> >> _______________________________________________
> >> erlang-questions mailing list
> >> erlang-questions@REDACTED
> >> http://erlang.org/mailman/listinfo/erlang-questions
> >
> >
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20111106/1e8adb77/attachment.htm>


More information about the erlang-questions mailing list