我发现在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,并且返回值被正确使用。
在其他地方测试detail_db和stats_db生成正确值的能力。
%% module mymod handle_announce(Announce,[DetailsDb,StatsDb]) -> AnnounceDetails = DetailsDb:fetch_details(Announce),AnnounceStats = StatsDb:fetch_stats(Announce),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和(this other one),但我不满意。
你如何单元测试你的erlang代码?
谢谢!
您需要将所有代码分成两种不同类型的模块:
(您应该阅读,并确保您了解差异 – 最典型的副作用 – 您的示例代码中的代码 – 正在写入数据库)。
纯功能的模块变得不容易测试。当输入相同的值时,每个导出的函数(按定义)总是返回相同的值。您可以使用Richard Carlsson和Mickael Remond写的EUnit/Assert框架。 Bish-bash-bosh,工作是一个很好的’un …
关键是,大约90%的代码应该在纯功能模块中 – 你大大缩减了你的问题。 (你可能会认为这不是“解决”你的问题,只是“减少”,而且你大都是对的)
一旦实现了这种分离,单元测试模块的最佳方法就是使用standard test framework。
我们这样做的方式不是使用mock对象,而是将数据库加载到init_per_suite或init_per_test函数中,然后自己运行模块…
最好的方法是尽快将其直接转移到系统测试中,因为单元测试是一个难以维护的单元测试 – 足够的单元测试可以让您进行系统测试往返,而不再需要(甚至更好的删除db单元尽快进行测试)。