Fork me on GitHub

I am using datomic client api and hence I have the (d/q foobar) function calls in my codebase. During testing, I want to mask out these functions and return faked ones. What’s the recommended approach to do that? Going with with-redefs or extending some protocol, if the latter, what protocol?

Lennart Buit11:06:54

The db object implements a protocol that supplies (the implementation of) d/q. What we have in our app is a wrapper that intercepts some of those protocol functions and (possibly) amends/replaces their implementation. For one, we have a wrapper for d/q logging queries and their results to a tap.


Hi. Can you be more concrete on a wrapper intercepting the protocol function?


How do you achieve this functionality?


you could achieve that via a defrecord implementing said protocol

Lennart Buit17:06:00

Yeah, we just have a deftype somewhere that forwards most calls to the ‘original’ db/`connection`/`client`, but amends their implementation:

(deftype MyWrappedDb [orig]
  (q [_ arg-map] (println arg-map) (datomic.impl/q orig arg-map))
That said, I’m not saying you should do this — I think its perhaps better to use dev-local to create a memory db for testing, but if you ever feel like you need to intercept calls on db values, this is a way to do so.

Joe Lane18:06:12

@UGC0NEP4Y that protocol is an impl detail and subject to change. I'd like to go back to your original problem statement. What problem will you solve when you "mask out these functions and return faked ones."?


I want to avoid connecting to real database for testing some functions that indirectly writes to db.

Joe Lane13:06:06

On-Prem or cloud?

Joe Lane14:06:24

Both and have equivalent memory databases which you could create and tear down for every unit-test, no production-code modification required.