Adding unit tests to a J2EE application

I got asked a very simple question today: how do you go about adding unit tests to an already existing J2EE app? In particular, so you can test your logic standalone, without needing to go through a deployment cycle and test it in the server?

My interlocutor made the very good point that when you develop a J2EE application test-first (as I advocate), you usually end up with a very good set of “mocks” for the various services provided by the container. However, writing these so you can test a class is a lot of effort (though it will pay itself back in time). So, was there an easier way?

This is what I replied:

One option is, of course, not to test your component in isolation. That is, instead of focusing on unit tests, look at writing integration-level tests that operate against a deployed version of your system. This typically means that your tests are slower, but usually gives benefits.

Another option is to take a very piecemeal approach. This is going to be sort of hard to explain, but here goes…

You’re writing a test for a piece of functionality, right? Move the business logic for the functionality into a method by itself, and then have other methods that use the J2EE environment to provide the data for the logic. You can then write a unit test for the business-logic method (which is typically where the errors are), plugging in sample data. At this stage, you hope that the environment stuff works (more accurately, you rely on integration level tests to show that).

Lather-rinse-and-repeat this for the entire class. You will ultimately end up with a lot of methods that provide your functionality, and another lot of methods that hook that functionality in the environment. The functionality will be fully tested through JUnit tests, and the “hooks” through integration-level tests.

Okay, now for the next step… yank all of the business functionality out into another class, leaving delegate methods back in the original class. Move your unit tests to suit. What you should now have is a single POJO class that has a lot of business logic, and a J2EE-based class that integrates the business logic back into your class. The aim here is to totally divorce your business logic from the environment.

At this point, you probably have a semi-decent abstraction of the services the environment provides for. You’ll probably even have good mocks for them. However, at no point have you taken a big overwhelming step. Of course, to get to the end goal will take a lot of time.

The ultimate trick is to stop thinking “I’m writing a J2EE application”, and start thinking “I’m writing an application that uses external services, one possible implementation of which is J2EE”.

Some footnotes:

  • There was a blog post I read not long back on this point, of treating J2EE as a service. The exact example I was read was how you could create a simple lookup service, and supply a JNDI-based implementation or a mocked one, so as to avoid having to mock out the more complex JNDI interface. Unfortunately, I couldn’t hunt down where I read that, so I can’t give credit where credit is due, alas.
  • If anyone else out there is stuck with a big ball of mud, this is the definitive article on unsticking it…

Author: Robert Watkins

My name is Robert Watkins. I am a software developer and have been for over 18 years now. I currently work for people, but my opinions here are in no way endorsed by them (which is cool; their opinions aren’t endorsed by me either). My main professional interests are in Java development, using Agile methods, with a historical focus on building web based applications. I’m also a Mac-fan and love my iPhone, which I’m currently learning how to code for. I live and work in Brisbane, Australia, but I grew up in the Northern Territory, and still find Brisbane too cold (after 16 years here). I’m married, with two children and one cat. My politics are socialist in tendency, my religious affiliation is atheist (aka “none of the above”), my attitude is condescending and my moral standing is lying down.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s