In one of my tests, I was trying to mock something (`clojure.tools.logging/warn`) that happened to be a macro. It had me puzzled for a while until I discovered that `with-redefs` resets the value of the vars after the body is executed, but does not reset the flag that says that the var is a macro:
$ lein repl
Clojure 1.6.0
…
user=> (defmacro foo [] `(prn "I am a macro"))
#'user/foo
user=> (clojure.test/function? 'foo)
false
user=> (with-redefs [foo (fn [] 42)])
nil
user=> (clojure.test/function? foo)
true
user=> (foo)
ArityException Wrong number of args (0) passed to: user/foo clojure.lang.AFn.throwArity (AFn.java:429)
user=> (foo 42 42)
(clojure.core/prn "I am a macro")
Is this a bug?
I looked at the source for `with-redefs-fn`, and the fix appears simple: record for each val whether it's a macro or not, and then call the `(setMacro)` method on the vars that should be macros after resetting their values.
Vebjorn