在Clojure和Midje中,如何编写间接调用的先决条件



在下面的代码中,我想在实现bar函数之前测试foo函数。

(unfinished bar)
(def tbl {:ev1 bar})
(defn foo [ev] ((tbl ev)))
(fact "about an indirect call"
  (foo :ev1) => nil
  (provided
    (bar) => nil))

但米杰说:

FAIL at (core_test.clj:86)
These calls were not made the right number of times:
    (bar) [expected at least once, actually never called]
FAIL "about an indirect call" at (core_test.clj:84)
    Expected: nil
      Actual: java.lang.Error: #'bar has no implementation,
      but it was called like this:
(bar )

我认为"provided"无法挂接bar函数,因为foo没有直接调用bar。但我也发现,如果我把第二行改成这样:

(def tbl {:ev1 #(bar)})

然后测试成功了。

第一个版本有什么成功的方法吗?

谢谢。

附言:我使用的是Clojure 1.5.1和Midje 1.5.1。

provided使用with-redefs的味道来更改var的根。定义tbl时,您已经取消引用var #'bar,提示tbl包含未绑定的值,而不是对要执行的逻辑的引用。我想说的是,你不能为已经评估的值提供替代品。

类似:

(defn x [] 0)
(def tbl {:x x})
(defn x [] 1)
((:x tbl)) ;; => 0

您想要的是将var本身存储在tbl:中

(defn x [] 0)
(def tbl {:x #'x})
(defn x [] 1)
((:x tbl)) ;; => 1

你的测试也是如此。一旦使用(def tbl {:ev1 #'bar}),它们就会通过。

最新更新