Post Today 10:36:05 AM Subject: Non J2EE transactional management in Java
I've been in this situation before, and what you need to know first off is that any unit test that involves a database, is not a unit test. Unit tests, the true meaning of them anyway, is a test that's completely, 100%, isolated from outside interactions.
In short, you can write JUnit test cases (not all JUnit tests are unit tests, nor do they need to be) that access a database but they are painful to write, at best, because you need to setup test data. Often times, I've used a JUnit's setUp/tearDown methods to setup database data, but its not for the faint of heart since the ability to screw things up is high, especially if your test case fail. At the very least, such a thing should never be run on a production database.
I'm guessing you have a business requirement (boss perhaps?) that is asking for unit tests of database-related code (often is the case). You have 4 choices:
# 1. Try to get out of it by explaining that database/transactional test cases are not unit tests, but integration/system testing.
# 2. Write JUnit tests that setup test data in the database before/after the test has been run
# 3. Use a tool to fake a database specifically made for testing. Believe it or not such tools do exist, although they can be cumbersome to use. I once used this product for testing and simulating a database: Agitator
# 4. Rewrite your classes so that all the 'important' business logic is in non-database related functions that can be tested as a unit. Systems that use object-relational mapping tools adapt naturally to this pattern.
kartik krishnan wrote:This is root of the problem. I am not sure how to do this. Ideally the data in the database would be restored to a known state after the test execution and the states before and after the execution would exactly match. So after an insert query (say), I need to be able to rollback to a previous known state.