문제

How do I test a higher-order function in Clojure ?

I can always test a function that accepts a value and then check returned value against the expected one.

How do I do that with a higher order function ?

Or we generally avoid doing so ?

도움이 되었습니까?

해결책

This is a good question. To be more precise about the issue:

Higher-order functions "take or produce other functions as arguments or results". So there's two cases:

  1. functions that take functions. Examples: map, reduce, filter. These aren't too hard to test; just supply all the parameters like you would to a normal function.

  2. functions that return functions. Examples: (fn [x] (fn [y] (+ x y))), (partial filter #(> % 1)). These are difficult to test because we can't directly compare the equality of functions (search for intensional and extensional equality for a thorough discussion).

    It should be obvious that simply not testing is not a very good strategy. So why not take the Haskell view that partially applied functions are essentially the same as functions that return functions -- in other words, pass enough parameters to the returned function to get a result that you can test for equality.

    Just be careful to watch out for coupling in your tests -- make sure that your test cases are actually testing the specification of the higher-order function, not just the function that it returns.

다른 팁

Higher order functions still return results so you can still check it.

For example, if you wanted to test map, think about what it's supposed to do: It is supposed to get a function and a collection as arguments, apply said function to every item in the collection, returning a new collection of the results.

So a simple way of testing that would be:

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

The same principle applies if you're testing a higher-order function that is the result of another function: you simply test it returns what's supposed to, after calling the function that returns it:

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

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

Hope this helps.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top