views:

3115

answers:

9

This may be a naive question, but I am new to both the junit and hibernate frameworks and I was wondering what the best way to go about unit testing an application that is largely calls to hibernate, or if it is even necessary to do so?

What is the best practice here?

EDIT:
Spring seems to be the big suggestion here. Unfortunately this may be alittle too much to bite off for one project. Junit, hibernate and spring are all new to me, and while they are all technologies I want to get under my belt, I think trying to incorporate them all into one project may be too overwhelming for me.

Links to tutorials and/or book suggestions are welcome.

A: 

Sure, you'd unit test your persistence tier if it wasn't written in Hibernate, wouldn't you?

Create a given persistence interface that's implemented using Hibernate, instantiate some sample objects, perform CRUD operations, and ask JUnit to assert that the operations were successful. Same as any other class.

duffymo
+1  A: 

Best practice? I use Spring and make all my tests transactional. I perform the test and rollback all the changes so I don't change the state of the database.

duffymo
Our database's are notoriously unreliable, and even if they weren't doesn't the act of using an external system make it an integration test and not a unit test?
James McMahon
A: 

You could use Spring to help here.

It has a great unit test framework, you can use it to test CRUD ops and then rollback changes - great if you don't have the capability to reload a database every time.

Fortyrunner
+3  A: 

As for best practices:

use an embedded database for running your tests if possible, so that you don't need a full deployed relational database just to run your tests (locally, or on your continuous build server if you have one). That way you also don't need to (necessarily) worry about rolling back etc, you can just recreate the database when you need to. Testing with an embedded database doesnt test peculiarities that could come up when you use your specific production database, but it does test your code, which should suffice.

You can also use DbUnit, an extension to JUnit, to easily fill the database with expected rows and put it in a known state, before you run your Hibernate tests.

Raymond Roestenburg
It's worth to note here that this will be integration test.
Alexey
A: 

I like to use a in memory hsqldb for testing. The process for each hibernate POJO is:

  1. Create the object
  2. Persist it to the DB
  3. Clear the session
  4. Get it from the DB
  5. Assert the objects are equal.

For DAOs, I create and persist enough objects to accurately test the methods, then run the tests and delete the objects as necessary to not intefere with other tests.

jon077
So you are essentially testing the mappings here? Correct?
James McMahon
+7  A: 

Keep in mind the difference between unit testing and integration testing.

Unit tests should be testing code without any outside dependencies. These dependencies are mocked using a framework like, for example, JMock.

Integration tests are important too but the major drawback of them is that they take a long time to run. You can run thousands of true unit tests in a couple of seconds, but it's not the same with integration tests.

Depending on the size of your project/development team you might want to prioritize true unit tests over integration tests. Both style of tests are important but if you are pressed for resources, just going with Unit testing may be a better idea.

I wrote an application by myself that unit tested the Web (with Spring MVC this is easy) and Service layers, as well as domain objects. But I left the DAO alone because I didn't want to write a bunch of slow integration tests. If I had more people on staff I would have gone with integration tests as well, but in this case I didn't feel the time spent would be worth it.

bpapa
I've heard of Jmock before, how does one use it with Hibernate?
James McMahon
There definitely is a difference between unit tests and integration tests I agree. Just to add, there is also a difference between mockist and classical style of unit testing. it all depends on how fast (and scaled) your continuous build server is :)
Raymond Roestenburg
I concur with spending the time elsewhere. The projects I've worked on with Hibernate have always ended up with a thin layer over Hibernate and tested up to that point and mocked that layer out. If that thin layer of code is brokem it will show up real quick in sanity checks
MrWiggles
+1  A: 

Hibernate source includes a lot of unit tests, I would recommend going through those and adapting a similar approach.

You can also look at the CaveatEmptor which the sample application developed for the book "Java Persistence with Hibernate"

kamal.gs
Is it redundant to unit test your frameworks in your application?
James McMahon
I wasn't suggesting testing hibernate, but the approach used can be adapted for your testing your application code - for example queries etc. The hibernate test suite includes such tests (though their aim is to verify that the framework works correctly).
kamal.gs
+3  A: 

The book Test Driven: TDD and Acceptance TDD for Java Developers has an entire chapter on testing data access including Hibernate (within the context of Spring). It includes unit and integration testing (with code examples) and the differences between the two.

Brandon
+1  A: 

Write a simple layer that passes requests to Hibernate. Then use a mocking library like EasyMock or JMock to assert that your Hibernate-veneer layer is correctly called by your application classes. This is nicely described in the partially-complete JMock book (scroll down to the test smell "everything is mocked").

Douglas Squirrel