Reputation: 1077
I am trying to use with-redefs
and reify
to mock methods in clojure. I do not have a clue on where to get started with those. Can anyone please give me an example of mocking a method? The documentation on the internet is of no help for me as I am totally confused with it at this point of time.
Upvotes: 3
Views: 1488
Reputation: 4300
Let's say you want to spy/mock/stub a function bar
and test how many times it got called in function foo
. A simple example could be:
(defn bar [] ...)
(defn foo []
(bar)
(bar)
(bar))
(deftest
(let [args (atom [])]
(with-redefs [bar (fn [x] (swap! args conj x))]
(foo)
(is (= (count @args) 3)))))
Well, I agree the code above is a bit tedious. You can try out the following macro: (I put invoke history into meta data)
(defmacro with-mock [vr & body]
`(with-redefs [~vr (with-meta
(fn [& ~'args] (swap! (-> ~vr meta :args) conj ~'args))
{:args (atom [])})]
(do ~@body)))
(with-mock bar
(foo)
(is (= (-> bar meta :args deref count)
3)))
With a little utilities functions, the macro above could become a powerful tool. The expressiveness of Clojure is so great.
Upvotes: 1
Reputation: 725
The book "The Joy of Clojure (Manning)" might be a good starting point, section '13.2 Testing' has some information with regards to (among others) the technique you mentioned - using the with-redefs
macro.
Upvotes: 3