9

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

4

2 回答 2

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 或惰性序列生成了值,则返回 true。”

于 2009-11-01T05:55:49.927 回答
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!"))

由于我们知道 map 是惰性的,所以它应该始终在这一点上工作。现在,强制评估序列:

(dorun result)

并再次检查 effect-count 的值。这一次,我们确实预计会触发副作用。而且,原来如此……

user=>@effect-count
9
于 2009-10-31T16:57:59.023 回答