在Java编写代码时,采用组合和依赖注入非常有帮助,通过模拟协作对象可以轻松进行纯单元测试。
我发现在Erlang中做同样的事情不太直接,会使代码变得更加混乱。
这可能是我的错,因为我对Erlang还很陌生,而且很沉迷于JUnit、EasyMock和java接口...
假设我有这个愚蠢的函数:
%% module mymod
handle_announce(Announce) ->
AnnounceDetails = details_db:fetch_details(Announce),
AnnounceStats = stats_db:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
在对 mymod
进行单元测试时,我只想证明 details_db
和 stats_db
被传递了正确的参数,并且返回值被正确使用。而 details_db
和 stats_db
生成正确值的能力已在其他地方进行了测试。
为了解决这个问题,我可以通过以下方式重构我的代码:
%% module mymod
handle_announce(Announce, [DetailsDb, StatsDb]) ->
AnnounceDetails = DetailsDb:fetch_details(Announce),
AnnounceStats = StatsDb:fetch_stats(Announce),
{AnnounceDetails, AnnounceStats}.
可以这样进行测试(基本上是将调用直接存根到测试模块中):
%% 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.
它能够工作,但应用程序代码变得混乱,我总是不得不携带那个丑陋的模块列表。
我尝试过几个模拟库(erlymock 和 (另一个) 但我并不满意。
你如何对你的Erlang代码进行单元测试?
谢谢!