The Spring fallacy
Spring proponents will have you believe that "Unit Testing" of persistent classes is very hard without spring. This is not the case, and can be accomplished in only a few classes.
This is not spring-bashing - I'm sure that Spring is very useful for some. This is simply an alternative approach to one that was presented at InfoQ
Requirements
To use these examples you will need the following libraries - all open source
- Hibernate
- Using Oracle Jars http://www.oracle.com - then sign up
- Hamcrest
- J2EE Api - whereever you can get it.
Persistance
We will be using a simple annotated class just to show the example.
The Persistent Stuff
This is where you might have used the ejbFindBy methods back in the day... its just an interface.. so you can conveniently have mocks and stubs for them.
And an implementation for the interface
Using an EntityManager. This means that we will create them in the transactional context in which they are used, rather than having them around for ever - as we might have used with an EntityManagerFactory. Short lived objects are very efficent these days.
Transactional Context
If we are to have any hope of using the entity manager outside of a J2EE container, then we need to do so within a transaction. Managing this as part of a testcase is a bit hit-and-miss - better abstract it.
Creating a test Configuration
All systems have some way of getting their configuration. In real code the implementation here would be a little more intelligent.
Creating a test Entity Manager
This example uses Hibernate and Oracle, but you could do this with lots of other implementations. Note that the actual implementation doesn't escape - as far as the rest of the code is concerned, we are still only talking about EntityManagers.
To keep the amount of code in this page short - I used the autoDDL feature of hibernate. I would suggest never do this, and make sure to have a good database rebuilding script as part of the build process. Dropping and recreating databases takes only seconds.
Builders
We like to use the Builder pattern - it makes code much cleaner!
The actual persistence test
How it all looks
Here's a screenshot from IntelliJ after we have put all the code together.
Contact me - using the contact me page if you would like access to the svn repo. All the code is here though.
Screenshot

Thanks
Nat & Nick
Complaints
To me...
12 Comments
Hide/Show CommentsNov 21, 2007
Anonymous
This is helpful, thanks for the post. Perhaps your own article on InfoQ next time?
JAW
http://jawspeak.com
Feb 05, 2008
Anonymous
The matcher should be hasSameTransientFieldsAs, not hasSameNonTransientFieldsAs,
Aug 12, 2009
Anonymous
well, too much code to achieve the same thing compared using spring.
Feb 17, 2010
Anonymous
Much code ? Even considering spring-xxx.jar ?
EricMinio
Feb 08, 2012
Anonymous
Feb 17, 2010
Anonymous
I like the way you've managed to simplfy JUnit testing and my team and l, are going to go with your approach.You've greatly simplified the approach that Spring uses, and you've taken away the dependency of Unit testing using Spring, you approach seems seemless and easier to use.
Feb 18, 2010
James Richardson
Thanks - The approach is documented in greater detail in Growing Object Oriented Software Guided By Tests
I find that by just using plain old java with sensible constructors and no pointless frameworks code stays clean and totally refactorable.
You can contact me using the Contact Us page if you wanted more information etc (saves my posting my email address for scammers here!)
Sep 11, 2010
Anonymous
James,
I actually like your approach quite a bit, though I notice your domain object (Loan) does not contain any behavior. It's merely getters and setters.
If you needed to inject some sort of behavior into the object (Composites, Strategy objects etc), how would you accomplish that? Through constructor injection?
Or are you more of a fat service advocate?
Thanks for the great post.
I realize this post was a while ago, but I thought I'd ask in case you are monitoring.
Sep 13, 2010
James Richardson
Good question.
The Loan object doesn't do anything here. The point of the article was about handling the persistent fields, and checking that they round trip into the database.
If you did need it to do something, then you can of course just write some methods!
I'm not quite sure what you mean about "injecting behaviour" though. If an object needs a collaborator to do something then you can just give it to the object when you ask it to do that thing.
e.g.
Some methods may not need an obvious external service, but may instead just execute in a transactional context.
e.g.
Feb 08, 2012
Anonymous
Feb 09, 2012
Anonymous
Feb 09, 2012
Anonymous