如何在Clojure中测试高阶函数?
我总是可以测试一个接受值的函数,然后根据预期值检查返回值。
如何使用更高阶函数执行此操作?
或者我们通常会避免这样做?
答案 0 :(得分:4)
这是一个很好的问题。更准确地说是这个问题:
Higher-order functions“接受或产生其他函数作为参数或结果”。所以有两种情况:
带函数的函数。示例:map
,reduce
,filter
。这些都不难测试;只需提供与普通功能相同的所有参数。
返回函数的函数。示例:(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))
希望这有帮助。