On Monday, 25 March 2013 06:45:32 UTC+5:30, Leif wrote: > > Hello, fellow Clojurians. > > One problem I've run into when stubbing fns is that with-redefs doesn't > play well with concurrency. E.g. > http://clojuredocs.org/clojure_core/clojure.core/with-redefs#example_994 > The problem arises because, quoting with-redef's docstring, "These > temporary changes will be visible in all threads." > > Let's say you're stubbing the fn 'f' with the fn 'stub'. Here is an > irritating sequence of events: > 1: test1 redefs f to stub, saving the initial fn > 2: test2 redefs f to stub, saving **the current value of f, which is stub > ** > 3: test1 completes, resetting f to its initial fn > 4: test2 completes, **resetting f to the stub fn** > 5: test3 starts, expecting the fn f to work normally, and fails > > We actually ran into the problem because there was a delay in our app's > init fn, and so the first one of our integration tests that ran permanently > rewrote some fns. I would imagine that this could even happen in unit > tests, though, if your test runner executed tests in parallel. > > Has anyone run into a similar problem, and come up with a safer way of > stubbing / mocking non-dynamic vars? >
If you could design the code around Primatic's Graph: https://github.com/Prismatic/plumbing it may be cleaner and easier to isolate the dependencies, hence making them easy to mock. Another (lengthier) approach would be to model anything mockable as a protocol, and pass the implementation as function argument. As a bonus, this lets one keep the code mostly unaware of impurity. For production and integration-tests initialize the application at its entry point and instantiate the chain of dependencies, then pass the top level dependencies as function arguments. For unit tests where you need a mock dependency, simply pass a mock implementation of the protocol as a function argument. In cases where the application has several reference types for complex state management, an inside-out design will probably help a lot together with this approach for testing. Shantanu -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/groups/opt_out.
