Hi.
When writing code in Java, it is very helpful to embrace composition and dependency injection to make it possible and easy to do pure unit testing by mocking collaborating objects.
I find that doing the same in Erlang is less straightforward and makes for dirtier code.
That's likely to be my fault, as I'm quite new to Erlang and quite addicted to JUnit, EasyMock and java interfaces...
Let's say I have this stupid function:
%% module mymod
handle_announce(Announce) ->
AnnounceDetails = details_db:fetch_details(Announce),
AnnounceStats = stats_db:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
When unit testing mymod
, I only want to prove that details_db
and stats_db
are invoked with the right parameters, and that the return values are the used correctly.
The ability od details_db
and stats_db
to generate correct value is tested in other places.
To solve the problem I could refactor my code this way:
%% module mymod
handle_announce(Announce, [DetailsDb, StatsDb]) ->
AnnounceDetails = DetailsDb:fetch_details(Announce),
AnnounceStats = StatsDb:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
And test it this way (basically stubbing the calls directly into the test module):
%% module mymod_test
handle_announce_test() ->
R = mymod:handle_announce({announce, a_value}, [?MODULE, ?MODULE, ?MODULE]),
?assertEqual({details,stats}, R).
fetch_details({announce, a_value}) ->
details.
fetch_stats({announce, a_value}) ->
stats.
It works, but the application code becomes dirty and I always have to carry around that ugly list of modules.
I've tried a couple of mock libraries (erlymock and (this other one) but I wasn't satisfied.
How do you unit test your erlang code?
Thanks!