如何在Clojure中测试高阶函数?

时间:2013-10-03 13:38:35

标签: unit-testing testing clojure functional-programming higher-order-functions

如何在Clojure中测试高阶函数?

我总是可以测试一个接受值的函数,然后根据预期值检查返回值。

如何使用更高阶函数执行此操作?

或者我们通常会避免这样做?

2 个答案:

答案 0 :(得分:4)

这是一个很好的问题。更准确地说是这个问题:

Higher-order functions“接受或产生其他函数作为参数或结果”。所以有两种情况:

  1. 带函数的函数。示例:mapreducefilter。这些都不难测试;只需提供与普通功能相同的所有参数。

  2. 返回函数的函数。示例:(fn [x] (fn [y] (+ x y)))(partial filter #(> % 1))。 这些很难测试,因为我们不能直接比较函数的相等性(为了彻底的讨论,寻找内涵和外延的平等)。

    显然,不测试不是一个非常好的策略。那么为什么不采用Haskell视图,部分应用的函数与返回函数的函数基本相同 - 换句话说,将足够的参数传递给返回的函数以获得可以测试相等性的结果。

    请注意在测试中注意耦合 - 确保测试用例实际测试的是高阶函数的规范,而不仅仅是它返回的函数。

答案 1 :(得分:2)

高阶函数仍会返回结果,因此您仍然可以检查它。

例如,如果你想测试map,请考虑它应该做什么:它应该将一个函数和一个集合作为参数,将所述函数应用于其中的每个项目收集,返回一个新的结果集合。

这是一种简单的测试方法:

(is (= [1 2 3 4] (map inc [0 1 2 3]))

如果您正在测试另一个函数导致的高阶函数,则同样的原则适用:您只需测试它,在调用返回它的函数后返回它应该是什么:

(defn adder [n]
  (fn [x]
    (+ x n)))

(is (= ((adder 10) 5) 15)) 

希望这有帮助。

相关问题