28 November 2010

Java EE 6 Integration Testing with Spring

Half a year ago, I created and published the jeeunit project to fill in some gaps for running integration tests on Java EE 6 components in an embedded EJB container, mainly targeted at Embedded Glassfish 3.x. One of the alternatives I considered and dismissed before writing my own solution was the Spring Test Context.

At the time, I was left with the impression you had to pollute your Java EE components with Spring annotations like @Transactional to make declarative transactions work in the Spring container, and I did not (and still do not) like the idea of writing XML just to create a couple of Java beans and wire them up.

After taking a closer look at Spring 3.0.x these days, I realized a number of facts which are not quite obvious from the Spring reference manual:
  • You can do most of your Spring configuration (but sadly not all of it!) in Java instead of XML, which makes your application context type-safe and easier to read, and gives you refactoring support from your IDE.
  • Spring supports some (but not all) of the Java EE 6 annotations as alternatives to its own flavours.
  • You can run Stateless Session Beans and JPA entities in a Spring container with declarative transactions without introducing dependencies on Spring APIs or annotations.
jeeunit now includes an example project jeeunit-example-test-spring demonstrating this approach. The details are documented in the jeeunit Wiki page Testing on Spring.

This solution is not intended to replace the original in-container-testing approach of jeeunit, because transactional Spring beans and EJBs have different run-time semantics. However, for many integration tests, these differences are irrelevant.

Using the Spring Test Context instead of Embedded Glassfish and jeeunit has two main advantages:
  • Spring starts noticeably faster than Embedded Glassfish.
  • Launching a single test from your suite is much easier than with jeeunit. E.g. in Eclipse, you can simply use Run as JUnit Test just as with plain old unit tests.

No comments: