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?
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.
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?
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.
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 🙂
(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*
)
I tried to with-redefs
clojure.core/with-open
but I felt very dirty 🙂
I'm suggesting mocking the function in your code that is calling with-db-transaction
instead.
Of course, it needs to only run that transaction 🙂
yeah..unfortunately that's the one under test
so somewhere in the non-db logic there is something I need to test
(it's a bit all tangled)
Which is why I asked those questions. You should separate out the non-DB logic from the TX persistence piece then.
Detangle it, and it becomes much more testable.
(if something is hard to test, it's probably designed poorly)
well it definitely is
not sure I will have time to refactor it
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