Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test higher order functions in Clojure?

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 ?

like image 887
Amogh Talpallikar Avatar asked Oct 03 '13 13:10

Amogh Talpallikar


1 Answers

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.

like image 145
Matt Fenwick Avatar answered Oct 04 '22 21:10

Matt Fenwick