Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration testing - Hibernate & DbUnit

I'm writing some integrations tests in JUnit. What happens here is that when i run all the tests together in a row (and not separately), the data persisted in the database always changes and the tests find unexpected data (inserted by the previous test) during their execution.

I was thinking to use DbUnit, but i wonder if it resets the auto-increment index between each execution or not (because the tests also check the IDs of the persisted entities).

Thanks

M.

like image 604
Mark Avatar asked Dec 08 '22 03:12

Mark


2 Answers

It's a best practice to put your database in a known state before a test execution and DBUnit provides everything required for that. But don't rely on auto incremented columns, put them also in your DBUnit dataset. Pros: you can manually verify the database state after executing a test that fails. Cons: you need to setup and to maintain datasets.

The other approach is to run each test method inside a transaction (and to rollback the transaction at the end of the execution). Pros: data are easier to setup and maintain (in the databse). Cons: Fixing a failed test is less convenient.

like image 131
Pascal Thivent Avatar answered Dec 14 '22 12:12

Pascal Thivent


You can either run single tests or if applicable groups of tests as a single transaction, and then roll back at the end. (This might be difficult if the tests themselves comprise multiple transactions and your db doens't support nested transactions or savepoints.)

Alternatively, have your test database created by scripts. DbUnit can help here, as can other database generators, such as LiquiBase, dbmaintain, dbmigrate You can then drop the entire database and recreate for each test or test group. The usefulness of this approach diminishes as the test dataset becomes large and overhead increases.

A final option is to not have your tests depend upon the generated id, since depending upon the generated value will create brittle tests. It's useful to test the generated id, so test these values for some tests, but I'm not sure there is value in testing the Ids for all tests.

EDIT: The OP asked about using hibernate to recreate the schema. This can be arranged by creating a new SessionFactory for each test and setting the "hibernate.hbm2ddl.auto" to "true" when building the SessionFactory. I mention the diminishing effectiveness of drop-create - it appies to this case too.

like image 41
mdma Avatar answered Dec 14 '22 10:12

mdma