如何在Clojure中进行副作用函数的单元测试



这个问题不是关于特定的库(尽管其中一些库最终会被使用),而是关于如何构建应用程序代码,使副作用函数单元测试成为可能。如果我们真的应该这么做?

显然,对纯无副作用的函数进行测试,传递输入并断言输出,这是清楚而简单的。

有两种(非常粗略的)测试类型,单元和集成。让我们在这里集中讨论单元测试。

那么,如果您有一个从文件中读取或写入文件的函数(例如,使用slurp/spit),或者使用数据库、环形应用程序或core.async通道,如何在Clojure中对这些东西进行单元测试?是否涉及模拟,如果是,应如何定义?是否涉及bindingwith-{redefs, redefs-fn, local-vars}?我应该定义defprotocol以便在单元测试期间具体化(又称mock?)实现吗?

测试的价值之一(主要价值?)是强制对应用程序代码进行更好的设计,所以在这个意义上,Clojure中的测试可能是特别的,你被迫以特定于应用程序代码的方式构建应用程序代码,以使Clojure的副作用功能单元测试成为可能?

或者我完全没有抓住要点?

p.S.1:我很乐意使用Clojure中小型应用程序进行工作和开发(当然还有一段路要走),尽管测试部分我还不完全清楚。

p.S.2:另一个重要的话题是Clojure中的集成测试,但它将需要一个单独的SO问题。

通常,测试代码时会产生副作用,即为测试实现设置和拆卸工件。这些创建了基本/初始状态,并有助于评估结果。

我强烈建议您尽可能避开with-redefs和朋友。我们在与外部服务的大多数交互中都使用协议,并在各处注入依赖项,因此测试很简单。当然,我们仍然试图使功能尽可能纯粹,并仔细管理效果,但总的来说,我们对需要时的协议感到满意。

最新更新