amitrathore / conjure

a mocking library for clojure
http://s-expressions.com
73 stars 9 forks source link

Nesting of mocking/stubbing does not work as expected #14

Open oliyh opened 8 years ago

oliyh commented 8 years ago

Hi,

I have noticed that when nesting mocking or stubbing macros, all the mocks or stubs are cleared out when the first macro exits which leads to unexpected behaviour.

Consider the following:

(defn foo [] "foo")
(defn bar [] "bar")

(defn nested-stubs-test []
  (cj/stubbing [foo "hello"]
                    (cj/stubbing [bar "goodbye"]
                                      (println (bar)))
                    (cj/verify-call-times-for foo 0)))

I would expect this to work, but I get the following exception:

user> (nested-stubs-test)
goodbye                                                                                                                                             
AssertionError Conjure macro verify-call-times-for was called on a function that was not specified in one of `conjure.core/mocking`, `conjure.core/stubbing`, or `conjure.core/instrumenting`  conjure.core/assert-conjurified-fn (core.clj:75)

It will only work if I keep all the stubbing calls nested, like so:

(defn nested-stubs-test []
  (cj/stubbing [foo "hello"]
                    (cj/stubbing [bar "goodbye"]
                                      (println (bar))
                                      (cj/verify-call-times-for foo 0))))

I believe this is because the atom tracking stubs is reset at the end of each with-installed-fakes call, rather than just dissoccing the stubbed functions. This makes it hard to write more involved tests where several steps may call the same functions but different return values and assertions are required.

oliyh commented 8 years ago

Ah, upon further investigation it seems that this is explicitly disallowed in v2.2.0 by this commit - my code above will throw an exception stating that nesting is not allowed. However in 2.1.3 (the version suggested in the README, which is what I am using) the code is allowed but results in the unexpected message I posted.

@AlexBaranosky I appreciate it was a long time ago, but why did you choose to disallow nested mocking rather than make changes to support it?