sql

All things SQL and JDBC...
richiardiandrea 2021-02-27T00:21:11.095Z

Hello again everyone, I am trying to unit test something via mocking (I know I know...), however, I don't know how to mock with-db-transaction...I tried mocking db-transaction* instead but it does not seem to work fine... What do other people do?

seancorfield 2021-02-27T00:33:09.097300Z

I either use a local test DB that is setup/torn down around the test suite (after all, we have migrations for every change we've made to the DB schema so running all the migrations from scratch locally is "easy"). For each test, the necessary DB state is setup (and cleaned up afterward). Or... I mock out just the routine that would persist the changes.

seancorfield 2021-02-27T00:34:05.098300Z

I guess I would ask: 1) what are you doing inside that transaction? 2) what else does that function that calls with-db-transaction do?

seancorfield 2021-02-27T00:36:05.100300Z

It may also help to remember that clojure.java.jdbc does not actually nest TX (because it's not supported by DBs), so you could have a test fixture that set up a TX, called the test, and then rolled back the TX. At that point, any TX that the code tries to set up as part of executing the test is just going to be ignored. That may not be the right semantic for you, but it's available as an option.

richiardiandrea 2021-02-27T00:38:04.101700Z

I am ok with mocking around transactions for this. I really don't need that. All the other db functions are mocked with with-redefs at this point but with-db-transaction is also trying to do with-open and therefore I need to pass something that it likes 🙂

seancorfield 2021-02-27T00:38:12.102100Z

(note: next.jdbc behaves differently there -- it deliberately allows you to overlap TX scopes but assumes you know what you're doing! you can get both the c.j.j behavior and a prohibition on attempts to nest TX -- by rebinding next.jdbc.transaction/*nested-tx*)

👍 1
richiardiandrea 2021-02-27T00:38:39.102200Z

I tried to with-redefs clojure.core/with-open but I felt very dirty 🙂

seancorfield 2021-02-27T00:38:47.102400Z

I'm suggesting mocking the function in your code that is calling with-db-transaction instead.

seancorfield 2021-02-27T00:39:04.102600Z

Of course, it needs to only run that transaction 🙂

richiardiandrea 2021-02-27T00:39:17.102800Z

yeah..unfortunately that's the one under test

richiardiandrea 2021-02-27T00:39:39.103Z

so somewhere in the non-db logic there is something I need to test

richiardiandrea 2021-02-27T00:39:49.103200Z

(it's a bit all tangled)

seancorfield 2021-02-27T00:40:00.103400Z

Which is why I asked those questions. You should separate out the non-DB logic from the TX persistence piece then.

seancorfield 2021-02-27T00:40:16.103600Z

Detangle it, and it becomes much more testable.

seancorfield 2021-02-27T00:40:34.103800Z

(if something is hard to test, it's probably designed poorly)

richiardiandrea 2021-02-27T00:41:38.104Z

well it definitely is

richiardiandrea 2021-02-27T00:41:51.104200Z

not sure I will have time to refactor it

richiardiandrea 2021-02-27T00:44:39.104500Z

but thanks Sean I guess I got my answer...it's not possible to do much unit testing (via mocks) here - better go for some other strategy