Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing Clojure单元测试:检查是否调用了函数_Unit Testing_Clojure_Mocking_Tdd_Midje - Fatal编程技术网

Unit testing Clojure单元测试:检查是否调用了函数

Unit testing Clojure单元测试:检查是否调用了函数,unit-testing,clojure,mocking,tdd,midje,Unit Testing,Clojure,Mocking,Tdd,Midje,我正在尝试为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))) 在单元测试此函数时,我想编写以下测试用例:

我正在尝试为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。

您可以自己编写一个宏来模拟函数,并检查函数是否被调用。或者你可以使用图书馆


您已经拥有的功能版本离工作功能版本不远了。我对Clojure做了一点改动,使其更习惯于Clojure

以下假设“生成天空节点”和“生成热节点”都返回一些值(除了它们具有的任何副作用外,还可以执行此操作),即:

然后,生成节点的调整如下所示:

(defn generate-nodes
  [sky-blue? hot-outside? name]
  (cond
   (sky-blue? name) (generate-sky-nodes)
   (hot-outside?) (generate-hot-nodes)))
最后,测试的功能版本:

(deftest when-sky-blue-then-generate-sky-nodes
  (let [truthy (constantly true)
        falsey (constantly false)
        name nil]
  (is (= (generate-nodes truthy falsey name)
         :sky-nodes))
  (is (= (generate-nodes truthy truthy name)
         :sky-nodes))
  (is (not (= (generate-nodes falsey falsey name)
              :sky-nodes)))
  (is (not (= (generate-nodes falsey truthy name)
              :sky-nodes)))))
一般的想法是,你不测试它做了什么,你测试它返回什么。然后安排代码,以便(只要可能)函数调用的所有重要内容都是它返回的内容

另一项建议是,通过使用
生成天空节点
生成热节点
返回要执行的副作用,将副作用发生的位置数量降至最低:

(defn generate-sky-nodes
   []
   (fn []
    (doseq [i (range 10)] (do-make-sky-node i))
    :sky-nodes))
您对
generate nodes
的调用如下所示:

(apply (generate-nodes blue-test hot-test name) [])
或者更简洁地说(如果你对Clojure不太熟悉的话,当然会觉得奇怪):

(在上述测试代码中作必要的修改后,测试也将使用此版本)

使用的是:

你可以用

(需要['mock-clj.core:as'm])
(当天空为蓝色时取消测试,然后生成天空节点。)
(m/带模拟[天蓝色吗?正确
生成天空节点nil]
(生成节点(fn[x]println“生成的天空节点”)……)
(是(m/称为?生成天空节点)))

问得好。在我看来,您正试图将命令式测试应用于声明性代码。你不应该描述事物是如何工作的,但是它们是做什么的,所以调用一个函数在我看来是一个无关紧要的细节。不过要得到函数编程专家的确认(我不是)。@guillaume31,我认为这就是mock和stub之间的区别。存根只是为了提供支持行为的假实现,而mock就是这样做的,同时也进行记帐。就我个人而言,即使在OO世界中,模仿也是一个非常糟糕的主意。在功能世界中,情况更是如此。但可能只有我一个人。@ivant Dunno。我猜存根仍然以某种方式描述了如何进行测试,尽管您可能无法没有它们来获得性能测试。我个人确实觉得模拟很有用,不是做微观核算,而是验证一个对象不会对它的一个对等对象说粗鲁的话(即协议外的话),这导致OO类型系统中这些协议缺乏流畅的执行。@guillaume31,我同意在我看来,这更有意义(在功能世界中)将该函数视为黑箱并测试它返回的内容。但在有些情况下,函数所做的只是一种副作用,你需要确保它以一种适当的方式影响世界。这对于还不熟悉函数范式的人来说是一个很好的例子+伟大的邮政!这种模式是否有一个名称,即副作用函数返回一个“令牌”,以帮助测试?只是一个警告:该库自2012年以来未更新,似乎与Clojure 1.9不兼容。
(defn generate-sky-nodes
   []
   (fn []
    (doseq [i (range 10)] (do-make-sky-node i))
    :sky-nodes))
(apply (generate-nodes blue-test hot-test name) [])
((generate-nodes blue-test hot-test name))
(unfinished is-sky-blue? hot-outside?)
(facts "about GenerateNodes"
  (fact "when the sky is blue then sky nodes are generated"
    (GenerateNodes is-sky-blue? hot-outside? ..name..) => ..sky-nodes..
    (provided
      (is-sky-blue? ..name..) => true
      (generate-sky-nodes)    => ..sky-nodes..
      (generate-hot-nodes)    => irrelevant :times 0)))