[erlang-questions] testing side effects of asynchronous code
Klas Johansson
klas.johansson@REDACTED
Fri Jan 6 20:02:19 CET 2012
2012/1/2 Motiejus Jakštys <desired.mta@REDACTED>:
> Hi List,
>
> Let's say I am testing side effects of this asynchronous function:
> gateway_api:send(Message) -> reference()
>
> It does some asynchronous processing and produces side effects. After
> processing completes, gen_gwserver:ack_sent is invoked, like this:
> gen_gwserver:ack_sent(Ref :: reference()) -> ok.
>
> The question is: how can I know that the function ack_sent has been
> called? Then I know that asynchronous work has been completed, so I can
> start validating the side effects.
>
> An imaginary API in a test case, which blocks until
> gen_gwserver:ack_sent/1 has been called:
> ?call_and_sleep(
> gateway_api:send(Message),
> gen_gwserver, ack_sent, 1
> )
>
> Some options that we ruled out:
> * timer:sleep(some random value)
> * making internal gateway_api:ack(Reference) calls (inconvenient, since
> necessary only for testing)
> * meck:passthrough looked promising, but the problem is it doesn't
> return, so it cannot be implemented using meck cleanly.
>
> Thanks,
> Motiejus Jakštys
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
Hi,
I'm biased here, but it sounds like mockgyver [1] could help you out.
mockgyver is a mocking library which also lets you verify
side-effects. There are a number of ways to verify side-effects, but
the one it sounds you're after is the ?WAIT_CALLED macro and you don't
have to (you can, but you don't have to) mock gen_gwserver in order to
use it. ?WAIT_CALLED relies on erlang traces for non-mocked modules.
Here's how you'd use it from eunit:
-include_lib("mockgyver/include/mockgyver.hrl").
api_test_() ->
?WITH_MOCKED_SETUP(fun setup/0, fun cleanup/1).
setup() ->
... start server here, if any ...
Pid.
cleanup(Pid) ->
... stop server here, if any ...
calls_gw_server_ack_test(Pid) ->
...
Ref = gateway_api:send(Message),
...
?WAIT_CALLED(gen_gwserver:ack_sent(Ref)), % matches only calls
with ref from above
... verify side-effects here, perhaps using ?WAS_CALLED ...
Cheers,
Klas
[1] https://github.com/klajo/mockgyver
https://github.com/klajo/mockgyver/blob/master/doc/mockgyver.md
More information about the erlang-questions
mailing list