6

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

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

我如何使用高阶函数来做到这一点?

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

4

2 回答 2

5

这是一个很好的问题。为了更准确地了解这个问题:

高阶函数“采用或产生其他函数作为参数或结果”。所以有两种情况:

  1. 接受函数的函数。例子:map, reduce, filter. 这些并不难测试。只需像普通函数一样提供所有参数。

  2. 返回函数的函数。例子:(fn [x] (fn [y] (+ x y))), (partial filter #(> % 1)). 这些很难测试,因为我们无法直接比较函数的相等性(搜索内涵和外延相等性进行彻底讨论)。

    很明显,简单地不测试并不是一个很好的策略。那么为什么不采用 Haskell 的观点,即部分应用的函数与返回函数的函数本质上是相同的——换句话说,将足够的参数传递给返回的函数以获得可以测试相等性的结果。

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

于 2013-10-03T14:10:43.587 回答
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)) 

希望这可以帮助。

于 2013-10-03T13:59:58.987 回答