In the following code, I'd like to test the foo function before implementing the bar function.
(unfinished bar)
(def tbl {:ev1 bar})
(defn foo [ev] ((tbl ev)))
(fact "about an indirect call"
(foo :ev1) => nil
(provided
(bar) => nil))
But Midje says:
FAIL at (core_test.clj:86)
These calls were not made the right number of times:
(bar) [expected at least once, actually never called]
FAIL "about an indirect call" at (core_test.clj:84)
Expected: nil
Actual: java.lang.Error: #'bar has no implementation,
but it was called like this:
(bar )
I thought that 'provided' couldn't hook the bar function because the foo didn't directly call the bar. But I also found if I changed the second line like this:
(def tbl {:ev1 #(bar)})
then the test succeeded.
Is there any way to succeed for the first version?
Thanks.
PS: I'm using Clojure 1.5.1 and Midje 1.5.1.
provided
uses a flavour of with-redefs
to alter the root of a var. When defining tbl
you already dereference the var #'bar
, prompting tbl
to contain the unbound value instead of a reference to the logic to be executed. You cannot provide replacements for already evaluated values is what I'm trying to say.
Similarly:
(defn x [] 0)
(def tbl {:x x})
(defn x [] 1)
((:x tbl)) ;; => 0
What you want is to store the var itself in tbl
:
(defn x [] 0)
(def tbl {:x #'x})
(defn x [] 1)
((:x tbl)) ;; => 1
Same for your tests. Once you use (def tbl {:ev1 #'bar})
, they pass.