[ACCEPTED]-Unit testing a Hibernate driven application?-junit
Keep in mind the difference between unit 24 testing and integration testing.
Unit tests 23 should be testing code without any outside 22 dependencies. These dependencies are mocked 21 using a framework like, for example, JMock.
Integration 20 tests are important too but the major drawback 19 of them is that they take a long time to 18 run. You can run thousands of true unit 17 tests in a couple of seconds, but it's not 16 the same with integration tests.
Depending 15 on the size of your project/development 14 team you might want to prioritize true unit 13 tests over integration tests. Both style 12 of tests are important but if you are pressed 11 for resources, just going with Unit testing 10 may be a better idea.
I wrote an application 9 by myself that unit tested the Web (with 8 Spring MVC this is easy) and Service layers, as 7 well as domain objects. But I left the DAO 6 alone because I didn't want to write a bunch 5 of slow integration tests. If I had more 4 people on staff I would have gone with 3 integration tests as well, but in this case 2 I didn't feel the time spent would be worth 1 it.
As for best practices:
use an embedded database 15 for running your tests if possible, so that 14 you don't need a full deployed relational 13 database just to run your tests (locally, or 12 on your continuous build server if you have 11 one). That way you also don't need to (necessarily) worry 10 about rolling back etc, you can just recreate 9 the database when you need to. Testing with 8 an embedded database doesnt test peculiarities 7 that could come up when you use your specific 6 production database, but it does test your 5 code, which should suffice.
You can also 4 use DbUnit, an extension to JUnit, to easily fill 3 the database with expected rows and put 2 it in a known state, before you run your 1 Hibernate tests.
Best practice? I use Spring and make all 3 my tests transactional. I perform the test 2 and rollback all the changes so I don't 1 change the state of the database.
I like to use a in memory hsqldb for testing. The 5 process for each hibernate POJO is:
- Create the object
- Persist it to the DB
- Clear the session
- Get it from the DB
- Assert the objects are equal.
For DAOs, I 4 create and persist enough objects to accurately 3 test the methods, then run the tests and 2 delete the objects as necessary to not intefere 1 with other tests.
Hibernate source includes a lot of unit 5 tests, I would recommend going through those 4 and adapting a similar approach.
You can 3 also look at the CaveatEmptor which the sample application 2 developed for the book "Java Persistence 1 with Hibernate"
If you're using Hibernate for Domain rich 11 models, Unit testing domain logic is as 10 simple as testing a POJO and Hibernate doesn't 9 get in your way. The only caveat here is, For 8 bidirectional mappings, you might have to 7 set the object on both sides for unit tests.
Integration 6 testing with database is generally not done 5 for simple mappings. However it is suggested 4 in the case of exquisite mappings like Single 3 table inheritance etc. The only thing to 2 remember here is, you may have to explicitly 1 flush to database sometimes.
Sure, you'd unit test your persistence tier 6 if it wasn't written in Hibernate, wouldn't 5 you?
Create a given persistence interface 4 that's implemented using Hibernate, instantiate 3 some sample objects, perform CRUD operations, and 2 ask JUnit to assert that the operations 1 were successful. Same as any other class.
You could use Spring to help here.
It has 4 a great unit test framework, you can use 3 it to test CRUD ops and then rollback changes 2 - great if you don't have the capability 1 to reload a database every time.
Write a simple layer that passes requests 6 to Hibernate. Then use a mocking library 5 like EasyMock or JMock to assert that your Hibernate-veneer 4 layer is correctly called by your application 3 classes. This is nicely described in the 2 partially-complete JMock book (scroll down to the 1 test smell "everything is mocked").
Two cases are easy to test:
When practical, perform 10 your various calculations and transformations 9 in functions that don't know about saving 8 or loading entities. If you can make these 7 pure functions, so much better.
For functions 6 that only save to the database without reading 5 from it, you can choose not to save when 4 testing.
The simplest (crudest) way to do 3 #2 is by adding a reallyUpdate
parameter to the function, then 2 surrounding each "save" call with:
if (reallyUpdate) {
HibernateUtil.saveOrUpdate(theThing);
}
For me 1 these were the lowest hanging fruit.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.