Unit testing and declarative transactions with Spring and Hibernate

I’ve developed a simple service for creating users in an application, which I want to unit test. The service’s methods are declared as transactional with Spring metadata (In my case, I’m using annotations).

public class UserServiceImp implements UserService {
  public void createUser(User u) {

When unit testing, I don’t want to get the service through Spring… I want to test the real class, so I create it. This means that Spring doesn’t have a chance for adding the instrumentation (a proxy in my case) to the service class.

The result is that I get one transaction for each of the HibernateTemplate invocations performed inside the testing methods and service implementation, and the transaction is always rolled back (nothing is persisted to the database). In case you wondered, that’s a bad thing… for example, if I want to test that user creation correcly detects attempts to duplicate a user, I need to add a user and assert that a second attempt fails.

Update: I’ve written a new post about a better way for testing this scenario.

The solution is to use a TransactionTemplate and include all the test code inside its doInTransaction method.

I find it useful (albeit noisy) to throw a RuntimeException as the last thing inside the transaction, forcing a rollback. This way I’m assured that my test database is never modified and tests are repeatable. Just pay attention to the excepciont thrown and catch it to avoid signaling a test failure.

public void testSomething() throws Exception {
  TransactionCallback transac = new TransactionCallbackWithoutResult() {
    protected void doInTransactionWithoutResult(
      org.springframework.transaction.TransactionStatus status) {
      throw new RuntimeException("Rollback forced");
  PlatformTransactionManager ptm =
    (PlatformTransactionManager) ctx.getBean("txManager");
  try {
    new TransactionTemplate(ptm).execute(transac);
  } catch (RuntimeException e) {
    if (e.getMessage().equals("Rollback forced")) {
      /* Swallow exception. */
    } else {
      throw e;

I’m aware that there are some things I should not be doing… specially accessing the Spring context from my unit test (I keep a different configuration file for those, though), but I’m not sure about the implications of doing it this way… it just looked as the easier and quicker path.

How is the rest of the world testing this? I’ve read about using mock objects to avoid hitting the database, but I haven’t seen anything which can work with the Spring+Hibernate combo out of the box.

Any suggestions?

  • My Open Source

  • Twitter Updates

    • @jacegu having said that, doctests are very important since they are what makes Elixir docs so useful, they document the external contract 1 hour ago
    • @jacegu not usually, this is the first time I see it done only with doctests. I should have added a few more cases as regular tests 1 hour ago
    • Was preparing a talk for @MadElixir with some code. Asked a question. Now trying to get a PR accepted in ElixirLang before the talk. 2 hours ago
    • Syntax-highlight some #ElixirLang code pygmentize -f rtf -O 'fontface=Monaco,style=native,fontse=52' -l ex elixir_source_file.ex | pbcopy 9 hours ago
    • Los mismos que no acudieron a la rueda de prensa, hoy dan la noticia de que nadie fue? đŸ¤” twitter.com/gisb_sus/statu… 23 hours ago
  • Enter your email address to follow this blog and receive notifications of new posts by email.

    Join 9 other followers

  • Flickr Photos

    Apertura Agile Open Spain 2011 - 32

    Apertura Agile Open Spain 2011 - 31

    Apertura Agile Open Spain 2011 - 30

    More Photos


Get every new post delivered to your Inbox.

%d bloggers like this: