I'm trying to write some unit tests for my clojure function (I'm using clojure.test, but I can switch to midje if necessary).
I have a function that reads like :
(defn GenerateNodes
[is-sky-blue? hot-outside? name]
(cond
(is-sky-blue? name) (generate-sky-nodes)
(hot-outside?) (generate-hot-nodes)))
when unit testing this function, I want to write the following test case :
(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?))
How can I assert that the function generate-sky-nodes was called ? or not ? I would use a mocking framework in C# or java, but I don't know about clojure.
What you have already is not far from a working functional version. I changed things around a bit to be more idiomatic to Clojure.
The following assumes that generate-sky-nodes and generate-hot-nodes each return some value (this can be done in addition to any side effects they have), i.e.:
then, your generate-nodes is adjusted as follows:
and finally, the functional version of the tests:
The general idea is that you don't test what it did, you test what it returns. Then you arrange your code such that (whenever possible) all that matters about a function call is what it returns.
An additional suggestion is to minimize the number of places where side effects happen by using
generate-sky-nodes
andgenerate-hot-nodes
to return the side effect to be carried out:and your call of
generate-nodes
would look like the following:or more succinctly (though admittedly odd if you are less familiar with Clojure):
(mutatis mutandis in the above test code the tests will work with this version as well)