Integration Testing - Hibernate & DbUnit

I am writing some integration tests in JUnit. What happens here is that when I run all the tests together in a row (and not separately), the data stored in the database always changes, and the tests detect unexpected data (inserted by the previous test) during their execution.

I was thinking of using DbUnit, but I am wondering if the auto-increment index is reset between each execution or not (because the tests also check the identifiers of the stored objects).

thanks

M.

+4
source share
4 answers

It is best to put your database in a known state before , and running DBUnit provides everything you need to do this. But don't rely on auto-growing columns; put them in your DBUnit dataset as well. Pros: you can manually check the status of the database after running a test that fails. Cons: you need to set up and save datasets.

Another approach is to run each test method inside a transaction (and roll back the transaction at the end of execution). Pros: Data is easier to configure and maintain (in the database). Cons: Correcting a failed test is less convenient.

+9
source

You can run single tests or groups of applicable groups as a single transaction, and then roll back at the end. (This can be tricky if the tests themselves contain multiple transactions, and your db does not support nested transactions or savepoints.)

Alternatively, create a test database created by scripts. DbUnit can help here, like other database generators like LiquiBase , dbmaintain , dbmigrate. Then you can delete the entire database and recreate for each test or test group. The usefulness of this approach decreases as the set of test data becomes large and overhead increases.

The final option is to ensure that your tests are not dependent on the generated identifier, since fragile tests will be created depending on the generated value. It is useful to test the generated identifier, so check these values ​​for some tests, but I'm not sure if there is any value when testing identifiers for all tests.

EDIT: OP asked to use sleep mode to recreate the circuit. This can be organized by creating a new SessionFactory for each test and setting "hibernate.hbm2dd.auto" to "true" when creating the SessionFactory. I mention the drop-create drop-efficiency - this also applies to this case.

+3
source

It's bad to rely on id values ​​in a test, because auto-increment depends only on the database. Therefore, I would never check the identifier, because if you do, your test depends on the fact that the entities are filled with specific identifier values, which are not an example of real life. The test must be independent of auto-increment identifiers.

+2
source

Essentially, the problem can be solved in two ways.

  • Wrap your database-related tests as part of a transaction. Before testing, the transaction. Upon completion of the test run, aborting the transaction always aborting the transaction. Thus, changes made in the test will not be saved.

  • Use something like DBUnit, etc. to mock classes related to database operations so that no data ever goes to the database and your classes return results as if the database operation was performed.

If you get access to the database while running your tests, I prefer approach 1.

+1
source

Source: https://habr.com/ru/post/1308682/


All Articles