如何对懒惰进行单元测试

Art*_*ldt 9 unit-testing clojure lazy-sequences

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

Tim*_*ley 9

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

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

(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
Run Code Online (Sandbox Code Playgroud)

从Clojure 1.3开始,还有一个realized?函数:"如果为promise,delay,future或lazy序列生成了一个值,则返回true."


lev*_*and 6

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

首先,将其设置为:

(def effect-count (ref 0))

(defn test-fn [x]
    (do
        (dosync (alter effect-count inc))
        x))
Run Code Online (Sandbox Code Playgroud)

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

(def result (map test-fn (range 1 10)))
Run Code Online (Sandbox Code Playgroud)

测试test-fn是否运行:

(if (= 0 @effect-count) 
    (println "Test passed!")
    (println "Test failed!"))
Run Code Online (Sandbox Code Playgroud)

既然我们知道地图是懒惰的,那么它应该始终在这一点上起作用.现在,强制评估序列:

(dorun result)
Run Code Online (Sandbox Code Playgroud)

并再次检查效果计数的值.这一次,我们预计会产生副作用.而且,它是如此......

user=>@effect-count
9
Run Code Online (Sandbox Code Playgroud)