duct

2019-02-01T15:25:15.119700Z

@weavejester: Have you ever wanted or wished for something like with-redefs but for integrant keys? Thinking for the testing case, where you want to stub out a component in a system. I do this currently by defining a new ig/init-key for the stub, meta-merging a test profile over the system with something like (let [system (ig/init (meta-merge main-system {:<http://service.to.be/stubbed|service.to.be/stubbed> (ig/ref :my.test/stub)}] ,,,)) However this requires a bunch of boiler plate defmethods especially when those components then need to contain a shared dep for the test to use; e.g. a atom/promise/core.async channel etc… Then the test needs to look into the system to pull out the references to those extra deps that it wants (e.g. the shared channel) which is pretty gross. It’d be nice to be able to do something that let me just define those stub deps in my local scope, rather than have to use defmethods etc. Any thoughts on this, or alternatives?

2019-02-01T15:26:38.120100Z

Not quite sure how such a thing might work in practice

2019-02-01T15:28:18.120800Z

hmmm actually I think I might have thought of a way to do it without requiring integrant features

2019-02-01T16:26:12.121800Z

@rickmoynihan I don't have any thoughts on stubbing out defmethods, except maybe by using :default or derive. I'd be interested in what you come up with, however.

2019-02-01T16:42:02.123800Z

Scratch that it turns out it doesn’t work 😞 I’m not sure this is possible without integrant changes… I think the nicest for a user might be for integrant to honor metadata on the RHS of a key that effectively says skip the defmethod constructor and use the value that’s here instead.

2019-02-01T16:42:36.124300Z

Hmm... I'd need to think about that.

2019-02-01T16:45:47.124800Z

yeah it definitely needs some thought but was thinking something like this:

(let [stub-chan (async/chan)
      system (ig/init (meta-merge main-system
                                  {:<http://service.to.be/stubbed|service.to.be/stubbed> ^:ig/stub (mock-service stub-chan)}] ,,,))

2019-02-01T16:47:31.125500Z

The problem with defmethod and derive are that they’re static.

2019-02-01T16:50:22.127Z

The other option would be to have ig/init take an additional overrides argument map… or have a new ig/init-with-stubs

2019-02-01T16:50:41.127200Z

that takes a map of stubs

2019-02-01T16:51:29.127900Z

Is stubbing multiple services really that useful? As opposed to just defining a global fake service to use?

2019-02-01T16:52:04.128700Z

e.g. :duct.database.sql/hikaricp vs. duct.database.sql/stub

2019-02-01T16:52:52.129700Z

I think it depends. The test here is an integration test; a large part of what it is testing is the base system config is wired up ok.

2019-02-01T16:53:44.130500Z

so yes, I can do that… but it’s a complex system; and once you start removing keys from the system and replacing them with others it becomes very hard to verify the test is right

2019-02-01T16:54:40.131400Z

I have considered doing this but it gets messy as you have to replace the ig/refs to the key; using something like clojure.walk.

2019-02-01T16:57:34.134100Z

Though I guess I can probably implement a generic swapper that walks and replaces keys easily enough… though for the test case it’s often useful for system values to come from a closure rather than config… Actually this might work with a single defmethod like:

(defmethod ig/init-key ::test [_ test-instance]
  test-instance)
and a walk/replace (whatever it’s called).

2019-02-01T16:58:08.135100Z

What about building something that simplifies (with-redefs [ig/init-key ...] ...)?

2019-02-01T16:58:58.136400Z

:thinking_face:

2019-02-01T16:59:00.136500Z

Like: (with-methods [ig/init-key {::foo (constantly {:a 1})}] ...)

2019-02-01T16:59:23.136900Z

So an equivalent of with-redefs but for multimethod keys.

2019-02-01T16:59:52.137200Z

Then it wouldn't have to be tied to Integrant at all.

2019-02-01T17:00:53.137500Z

That’s an interesting idea

2019-02-01T17:01:29.138Z

Should be quite easy too

2019-02-01T17:03:34.138200Z

Will try

2019-02-01T17:03:39.138400Z

thanks a lot

2019-02-01T17:04:57.138600Z

np