如何对懒惰进行单元测试

时间:2009-10-30 19:48:21

标签: unit-testing clojure lazy-sequences

我有一个函数应该采用懒惰的seq并返回一个未实现的懒惰seq。现在我想写一个单元测试(在test-is btw中)以确保结果是未实现的延迟序列

2 个答案:

答案 0 :(得分:9)

user=> (instance? clojure.lang.LazySeq (map + [1 2 3 4] [1 2 3 4]))
true

如果你有很多东西要测试,也许这会简化它:

(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

从Clojure 1.3开始,还有realized?函数:“如果为promise,delay,future或lazy sequence生成了一个值,则返回true。”

答案 1 :(得分:6)

将具有副作用的函数(例如,写入ref)用作测试用例中的序列生成器函数。如果副作用从未发生,则意味着序列仍然未实现......一旦实现序列,就会调用该函数。

首先,将其设置为:

(def effect-count (ref 0))

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

然后,运行你的功能。我只想使用地图,这里:

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

测试test-fn是否运行过:

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

因为我们知道地图是懒惰的,所以它应该始终在这一点上起作用。现在,强制评估序列:

(dorun result)

再次检查效果计数的值。这一次,我们预计会产生副作用。而且,就是这样......

user=>@effect-count
9