I\'m programming in Java and my applications are making a lot of use of DB. Hence, it is important for me to be able to test my DB usage easily.
What DB tests are all ab
Well to begin with ,are you using any ORM Layer for DB access?
If not : then what you are thinking would be of no use.What's the use of testing when you are not sure that SQL you are firing will work with your DB in production as in test cases you are using something else.
If yes:Then you can have look at various options pointed out.
new answer to old question (but things have moved forward a bit):
How to simulate a DB for testing (Java)?
you don't simulate it. you mock your repositiories and you don't test them or you use the same db in your tests and you test your sqls. All the in-memory dbs are not fully compatible so they won't give you full coverage and reliability. and never ever try to mock/simulate the deep db objects like connection, result set etc. it gives you no value at all and is a nightmare to develop and maintain
to have a personal testing DB is pretty impossible. You have to use a "public" DB, which is accessible for everyone
unfortunately a lot of companies still use that model but now we have docker and there are images for almost every db. commercial products have some limitations (like up to a few gb of data) that are non-important for tests. also you need your schema and structure to be created on this local db
"These tests sure ain't fast..." - DB tests tend to be slower than usual tests. It's really not ideal to have slow tests.
yes, db tests are slower but they are not that slow. I did some simple measurements and a typical test took 5-50ms. what takes time is the application startup. there are plenty of ways to speed this up:
you can also put the entire db into tmpfs
another helpful strategy is to have groups of tests and keep db tests turned off by default (if they really slows your build). this way if someone is actually working on db, he needs to pass additional flag in the cmd line or use IDE (testng groups and custom test selectors are perfect for this)
For each case a certain amount of insert/update queries should be made, which is annoying and takes time
'takes time' part was discussed above. is it annoying? I've seen two ways:
count(*)
in test B fails. it only grows because even when you delete some tests, you don't know which rows were used only by this one testhow do you know there are 542 rows in that table?" - One of the main principles in testing, is to be able to test the functionality in a way different from that of your tested-code
uhm... not really. the main principle is to check if your software generates desired output in response to specific input. so if you call dao.insert
542 times and then your dao.count
returns 542, it means your software works as specified. if you want, you can call commit/drop cache in between. Of course, sometimes you want to test your implementation instead of the contract and then you check if your dao changed the state of the db. but you always test sql A using sql B (insert vs select, sequence next_val vs returned value etc). yes, you'll always have the problem 'who will test my tests', and the answer is: no one, so keep them simple!
other tools that may help you:
testcontainers will help you provide real db.
dbunit - will help you clean the data between tests
cons:
testegration - intents to provide you full, ready to use and extensible lifecycle (disclosure: i'm a creator).
cons:
flyway or liquibase - db migration tools. they help you easily create schema and all the structures on your local db for tests.
I've used Hypersonic for this purpose. Basically, it's a JAR file (a pure Java in-memory database) that you can run in its own JVM or in your own JVM and while it's running, you have a database. Then you stop it and your database goes away. I've used it -- so far -- as a purely in-memory database. It's very simple to start and stop via Ant when running unit tests.
Java comes with Java DB.
That said, I would advise against using a different type of DB than what you use in production unless you go through an ORM layer. Otherwise, your SQL might not be as cross-platform as you think.
Also check out DbUnit
You could HSQLDB for in memory db testing. Starting the in memory data base and running tests on it is pretty straightforward.
http://hsqldb.org/
I agree with banjollity. Setting up isolated development and test environments should be a high priority. Every database system I've used is either open source or has a free developer edition you can install on your local workstation. This lets you develop against the same database dialect as production, gives you full admin access to development databases and is faster than using a remote server.