单元测试 – 如何在erlang中进行依赖注入和模拟?

前端之家收集整理的这篇文章主要介绍了单元测试 – 如何在erlang中进行依赖注入和模拟?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在Java中编写代码时,使用 compositiondependency injection可以轻松地通过嘲笑协作对象进行纯单元测试。

我发现在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单元尽快进行测试)。

猜你在找的设计模式相关文章