testing

Testing tools, testing philosophy & methodology...
2017-08-04T02:26:27.731543Z

is there a best practice for database testing, e.g mocks for clojure.java.jdbc?

roberto 2017-08-04T14:09:01.441797Z

when I want to mock something in clojure that has side effects, like database access or network io, I normally create a protocol for that, and then have a test and production implementation. Not sure if this is the best way to do it.

seancorfield 2017-08-04T15:55:45.326564Z

That's a reasonable way to do it, unless the surface area of the API you're using is big enough that becomes a pain.

seancorfield 2017-08-04T15:57:47.399641Z

An alternative is isolating your DB-accessing code from you business logic and testing the business logic separately -- more pure FP. Can be hard if you have a lot of DB access.

seancorfield 2017-08-04T15:58:33.427833Z

Or just use a test DB connection and setup/teardown test data around your tests. That's what we do for a lot of our data-intensive functions/tests.

mattly 2017-08-04T17:16:26.999844Z

I do the protocol thing as well, using a sort-of repository pattern defining specific queries and mutations against the database as well (or a part thereof).

mattly 2017-08-04T17:17:42.039959Z

for tests of the surrounding business logic, I can then mock the db with an in-memory store, and then the actual implementation that talks to the database has its own focused tests.

seancorfield 2017-08-04T17:47:55.041846Z

One important issue to bear in mind is that if you're trying to test actual SQL queries, you need to test it against a real database and it needs to be the one (you're planning to use) in production -- since the lightweight / in-memory / local file databases don't support the same SQL operations as the Big Ones do.

👍 1
seancorfield 2017-08-04T17:48:11.050903Z

@albaker So it really depends on exactly what you're trying to test.

2017-08-04T18:01:15.494523Z

I was thinking more like a lein profile w/ a testdb that gets spun up each time, or something along those lines

roberto 2017-08-04T18:08:32.740931Z

if you use protocols, you can have a testdb settings in your test that uses the testdb

roberto 2017-08-04T18:09:03.758223Z

the db name, host ,etc could be changed when that Database is initialized. I normally use a component for that

roberto 2017-08-04T18:09:22.768021Z

then all my queries in test use that component

roberto 2017-08-04T18:09:35.775331Z

in dev they use a different one, and in prod the production-ready one

roberto 2017-08-04T18:10:00.789073Z

you can externalize those settings too

seancorfield 2017-08-04T18:40:41.798953Z

Yeah, we have a Database Component (Stuart Sierra) and initialize it differently in dev/qa/prod (from external config files), then we have a dev-only script that tears down and builds a test DB (with a bunch of essentially random-but-conforming data). We use Boot so it's easy to write new build tasks (as Clojure functions) -- we have a lot of machinery in our build.boot file, including DB migrations (schema changes), data migrations (data changes), etc.

2017-08-04T21:12:52.043346Z

I find tests run quite fast against a db if I run them in a transaction and roll the transaction back — you can run your migration once at the start of the test suite and then run everything else on top of that