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.


Reply via email to