shrubbery
shrubbery copied to clipboard
Stubs with record semantics?
In my service I create components, and then they have config assoc'd onto them before they are started. The components adhere to the component Lifecycle, and also implement protocols for their behaviour.
Shrubbery is great for implementing the protocols, but when my system tries to assoc config into them, it fails because they are not records. Would it be possible to make an option where stubs behave like records?
That use case makes a lot of sense to me, but I haven't had a chance to think it through yet. I'm not opposed to the idea in principle—I'll take a look.
Here's an extremely minimal reify
implementation which can handle associng, but doesn't actually keep the keys. This is useful if you don't actually care about the config being assoc'd on, which happens in some cases, especially no-op components.
(defn new-null-reporter []
(reify
ErrorReporter
(-report-error [_ m]
nil)
;; Maplike impl follows
IPersistentCollection
(cons [this obj]
this)
(count [this]
0)
(empty [this]
this)
(equiv [this obj]
(identical? this obj))
Associative
(assoc [this k v]
this)
(containsKey [this k]
false)
(entryAt [this v]
nil)
ILookup
(valAt [this obj]
nil)
(valAt [this obj obj2]
nil)))
Oh that's extremely helpful, thank you!
From where you stand, do you think there's an argument to be made for making all stubs maplike, or should the library expose a secondary stub-record
function? If there's no harm in it—and particularly if it'd be non-breaking—I'm leaning towards the former.
I think it would be a pretty good default behaviour to have too. Part of me has a niggling fear that this could lead to latent bugs, where the stub accepts arguments that the real object wouldn't, if the user is stubbing something that isn't a record.
However I think using records is the more common scenario, and also a good design pattern. It could be good to have the default make a record-like, and then give people the option of creating the stub without record semantics if they really want it.