views:

153

answers:

2

I have a function that is supposed to take a lazy seq and return an unrealized lazy seq. Now I want to write a unit test (in test-is btw) to make sure that the result is an unrealized lazy sequence.

+3  A: 

Use a function with a side effect (say, writing to a ref) as the sequence generator function in your test case. If the side effect never happens, it means the sequence remains unrealized... as soon as the sequence is realized, the function will be called.

First, set it up like this:

(def effect-count (ref 0))

(defn test-fn [x]
    (do
        (dosync (alter effect-count inc))
        x))

Then, run your function. I'll just use map, here:

(def result (map test-fn (range 1 10)))

Test if test-fn ever ran:

(if (= 0 @effect-count) 
    (println "Test passed!")
    (println "Test failed!"))

Since we know map is lazy, it should always work at this point. Now, force evaluation of the sequence:

(dorun result)

And check the value of effect-count again. This time, we DO expect the side effect to have triggered. And, it is so...

user=>@effect-count
9
levand
I'm looking for a way to test any-function not a-function-to-test
Arthur Ulfeldt
+3  A: 
user=> (instance? clojure.lang.LazySeq (map + [1 2 3 4] [1 2 3 4]))
true

If you have a lot of things to test, maybe this would simplify it:

(defmacro is-lazy? [x] `(is (instance? clojure.lang.LazySeq ~x)))

user=> (is-lazy? 1)

FAIL in clojure.lang.PersistentList$EmptyList@1 (NO_SOURCE_FILE:7)
expected: (clojure.core/instance? clojure.lang.LazySeq 1)
  actual: (not (clojure.core/instance? clojure.lang.LazySeq 1))
false
user=> (is-lazy? (map + [1 2 3 4] [1 2 3 4]))
true
Timothy Pratley