【发布时间】:2013-08-22 03:22:27
【问题描述】:
我正在尝试为我的 clojure 函数编写一些单元测试(我正在使用 clojure.test,但如果需要我可以切换到 midje)。
我有一个函数,如下所示:
(defn GenerateNodes
[is-sky-blue? hot-outside? name]
(cond
(is-sky-blue? name) (generate-sky-nodes)
(hot-outside?) (generate-hot-nodes)))
当对这个函数进行单元测试时,我想编写如下测试用例:
(deftest when-sky-blue-then-generate-sky-nodes
(let [is-sky-blue true]
(GenerateNodes (fn[x] println "sky nodes generated."))
(is (= true Was-generate-hot-nodes-called?))
如何断言函数 generate-sky-nodes 被调用?或不 ? 我会在 C# 或 java 中使用模拟框架,但我不了解 clojure。
【问题讨论】:
-
好问题。在我看来,您正在尝试将命令式样式测试应用于声明性代码。您不应该描述 事物是如何工作的,而应该描述 what 它们的作用,因此调用的函数在 IMO 中是一个无关紧要的细节。不过有待函数式编程专家确认(我不是)。
-
@guillaume31,我认为这是模拟和存根之间的区别。存根只是为了提供支持行为的虚假实现,而模拟可以做到这一点,也可以做会计。就我个人而言,我发现模拟是非常糟糕的主意,即使在 OO 世界中也是如此。在功能世界中更是如此。但可能只有我一个人。
-
@ivant Dunno。我猜存根仍然以某种方式描述了如何,尽管您可能无法没有它们来获得性能测试。我个人认为 Mocks 很有用,不是做微记账,而是验证一个对象不会与它的对等点之一说话粗鲁(即外部协议),从而导致在 OO 类型系统中缺乏对这些协议的流畅执行。
-
@guillaume31,我同意在我看来,将函数视为黑盒并测试它返回的内容会更有意义(在函数式世界中)。但在某些情况下,函数所做的一切都是副作用,您希望确保它以适当的方式影响世界。
标签: unit-testing clojure mocking tdd midje