あなたがすでに持っているものは、動作する機能的なバージョンから遠く離れていません. Clojure により慣用的になるように、少し変更を加えました。
以下は、generate-sky-nodes と generate-hot-nodes がそれぞれ何らかの値を返すことを前提としています (これは、それらの副作用に加えて行うことができます)。
(defn generate-sky-nodes
[]
(doseq [i (range 10)] (do-make-sky-node i))
:sky-nodes)
次に、generate-nodes を次のように調整します。
(defn generate-nodes
[sky-blue? hot-outside? name]
(cond
(sky-blue? name) (generate-sky-nodes)
(hot-outside?) (generate-hot-nodes)))
そして最後に、テストの機能バージョン:
(deftest when-sky-blue-then-generate-sky-nodes
(let [truthy (constantly true)
falsey (constantly false)
name nil]
(is (= (generate-nodes truthy falsey name)
:sky-nodes))
(is (= (generate-nodes truthy truthy name)
:sky-nodes))
(is (not (= (generate-nodes falsey falsey name)
:sky-nodes)))
(is (not (= (generate-nodes falsey truthy name)
:sky-nodes)))))
一般的な考え方は、それが何をしたかをテストするのではなく、何を返すかをテストするということです。次に、(可能な限り) 関数呼び出しで重要なのは関数が返すものだけになるようにコードを調整します。
generate-sky-nodes
追加の提案は、使用して副作用が発生する場所の数を最小限に抑え、generate-hot-nodes
実行される副作用を返すことです。
(defn generate-sky-nodes
[]
(fn []
(doseq [i (range 10)] (do-make-sky-node i))
:sky-nodes))
の呼び出しはgenerate-nodes
次のようになります。
(apply (generate-nodes blue-test hot-test name) [])
またはもっと簡潔に (ただし、Clojure に慣れていない場合は奇妙ですが):
((generate-nodes blue-test hot-test name))
(上記のテストコードに必要な変更を加えて、テストはこのバージョンでも機能します)