11

clojure 関数の単体テストを書き込もうとしています (clojure.test を使用していますが、必要に応じて midje に切り替えることができます)。

次のような関数があります。

(defn GenerateNodes
   [is-sky-blue? hot-outside? name]
   (cond
     (is-sky-blue? name) (generate-sky-nodes)
     (hot-outside?) (generate-hot-nodes)))

この機能を単体テストするとき、次のテストケースを書きたいと思います:

(deftest when-sky-blue-then-generate-sky-nodes
   (let [is-sky-blue true]
       (GenerateNodes (fn[x] println "sky nodes generated."))
          (is (= true Was-generate-hot-nodes-called?))

関数 generate-sky-nodes が呼び出されたことをどのように主張できますか? か否か ?私は C# または Java でモック フレームワークを使用しますが、clojure については知りません。

4

4 に答える 4

11

あなたがすでに持っているものは、動作する機能的なバージョンから遠く離れていません. 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))

(上記のテストコードに必要な変更を加えて、テストはこのバージョンでも機能します)

于 2013-08-20T15:06:14.150 に答える
4

Midjecheckablesの使用:

(unfinished is-sky-blue? hot-outside?)
(facts "about GenerateNodes"
  (fact "when the sky is blue then sky nodes are generated"
    (GenerateNodes is-sky-blue? hot-outside? ..name..) => ..sky-nodes..
    (provided
      (is-sky-blue? ..name..) => true
      (generate-sky-nodes)    => ..sky-nodes..
      (generate-hot-nodes)    => irrelevant :times 0)))
于 2013-12-17T22:24:24.397 に答える