Archive for January, 2008

When to avoid the Container during Unit Testing

January 30th, 2008 by Oscar Huseyin

Over the course of my career, I have been eagerly reading, interviewing colleagues and experimenting with my own unit testing methodologies. It was only recently, that a fellow odecee colleague and I sat in a room and attempted to map out what we thought was a practical and repeatable unit testing methodology that we could take to other projects and cement a position on a unit testing pattern for odecee.

After brainstorming our ideas and categorising all the types of development testing, we were able to define a taxonomy that represented all types of tests that a development team should be creating. After some further refinement, I described the process in an odecee white paper with view to lay the foundations for odecee’s unit testing methodology.

Central to our discussions was the topic of this blog; when should a developer avoid testing in the container? To better illustrate the question, it’s best if I define what container avoidance is. First and foremost, all JEE applications will have a target deployment environment which typically includes an installation of some JEE container (WebSphere Application Server, Tomcat etc.) where the application that is being developed will be deployed to. Now, all containers provide foundation services to which the application can call upon to access some resource; albeit a database, LDAP directory, Connector, JMS provider, even the humble HTTPRequest object. The application under development will typically have a dependency on one or more resources managed by the container and will therefore need the services during the execution of the application. If you want to run your unit tests on an application that has a target container which is managing resources, then testing your application outside your container will require a strategy to provide replacements for your container managed services. The process in which a solution is derived that substitutes a container service for a fake one, albeit a stub or mock, is what I call container avoidance.

One implementation of a container avoidance strategy is to use an off-the-shelf framework like Spring, where each class in your application is configured as an “bean” and defined to have dependencies to other “beans”. Loosely coupling your java classes in this manner puts you in an ideal situation to abstract all your (potentially) container service providers. Now, swapping out your providers should be a simple configuration task; a task that can be abstracted by your unit testing framework, like the AbstractTransactionalDataSourceSpringContextTests. Seemingly simple really, but does require some planning and commitment to the testing pattern.

Once all your providers are abstracted, we have achieved container avoidance and can now run our primary test objects outside the container and weave our test code.

So, now that we have a method to avoid most container services, we’ve managed to reach further into our classes using our unit test code than ever before. Has this process increased the likelihood of a “works-first-time” deploy? No, it certainly has not. In the view to implement container avoidance, we’ve missed testing other aspects of the system under test, like Deployment Descriptors, System Configurations, View Concerns and many more things that make up the working application.

Although we have definitely achieved a engineering feat, l would characterise container avoidance as an academic task; one which can easily miss the pragmatic viewpoint of unit testing: proving the business function.

Well, where too from here? How far should we go with abstracting our providers? Only datasources? Only EJB’s? What about Web Services? It’s a tough question. And the answer depends on your philosophy of unit testing. Complex systems have many moving parts, orchastrated in a perfect harmony that will reliably deliver business value time and time again. Therefore, we should try our hardest to test the business functions and not the finest code granularity in a view to attain high levels of code coverage. This means using the container services by deploying your application and testing all facets of the system, including container configuration, in the test cycle. Lets not forget, if it was not for the services of the container, we would be forced to write multi-threaded applications on every customer engagement. Now that would surely be another engineering feat.

Is Dependency Injection only useful for Unit Testing?

January 7th, 2008 by Oscar Huseyin

The rise in popularity of Dependency Injection over the last three years has been an interesting observation. “Lightweight containers” like Spring and Pico have really intrigued and excited the masses of Java Developers, so much so, that Spring (for example) is automatically adopted and accepted to be mandatory for almost all J2EE applications.

Looking back to when I was first reading about Spring, I clearly recall how the DI concepts and simple semantics of the XML configurations really got my creative juices flowing. I remember thinking about all the possibilities the framework could offer; specifically the view of configuring all my components so they had no knowledge of their dependents. Just after I created my “Hello World!” application, I quickly realized that the concepts of the Abstract Factory had just been reinvented, this time under the “Lightweight Container” marketing. Sure, the framework provides externalised definitions of object dependencies and promotes coding to interfaces, but its no different than my trusted old Abstract Factory pattern. Ignoring my cautious voice, the shiny marketing got the better of me and I convinced myself Spring could present a better alternative to my novel approaches; I’d decided to use it on my next project.

After about three months of using Spring in angst, I recall moments where I was enjoying the flexibility I’d attributed to Spring. Spring promoted the definition of loosely coupled Java classes which really gave me an advantage during unit testing. Heck, with a bit of thought, I could wire every one of my java classes using Spring bean definitions and define all my dependents as a reference to another Spring bean. Now, I can pass in Mocks, Stubs, basically anything that implemented the contract. What power! It gave me incredible leverage to test my primary test object by mocking or stubbing my fixtures or dependents; now, obtaining higher levels of code coverage was really easy. I just had to ensure that all the java classes that I needed to test were defined as a Spring bean, making sure that all the primary test objects dependents were also defined as bean references. This way, by overriding specific bean definitions with Mock or Stub ones, I could replace them at runtime to exercise every concern of my application code.

One observation that I made during this time was the reduced number of the new operator usage. Looking though my source, everything was injected into my classes and the new operator had practically vanished. I recall the infamous “Dont call me, we’ll call you” cliche had whispered in my mind.

Looking back over my first Spring project, I’d say we achieved a test code coverage of about 80%. This was really exciting and I’d give all the credit to our decision to use Spring. A few years later, a few more gray hairs and a few more Spring enabled projects, I’ve realised that Spring is only an enabler to achieve high unit test code coverage. Sure, Spring privides some really nice JDBC, JNDI, JMS etc helpers, but the XML configurations aspect that it gives to an application can get really messy; so much so that it can become a real development impedance. How is this possible? Read my Aspects of Spring on a Monolithic Codebase blog; it sums up my growing pains.

So, the one resounding question that I have in my mind is “What real benefit does Spring offer to a system?”. After many discussions and hours of mental deliberation, I categorise the benefits of Spring by percentage as 90% unit testing flexibility and 10% utility.

Where to from here? Well, that depends on the importance you place on code coverage. Period. If your aiming for high levels of code coverage, then Spring’s your answer; just expect to deal with a pervasive XML configuration aspect of your codebase.

Proposing alternatives to Spring could be futile given the wild acceptance of the framework. In my humble view, Abstract Factories are formidable alternatives and can also be configuration driven and, again, cause a proliferation of dependency descriptor externalisation, however, they force you to think about your providers and give you a break from the Spring alternative to think about when you need to abstract your providers. This way, your decisions to define your configurable components can be made with more pragmatism and care.

In conclusion, using Spring has many advantages, most of which are, sadly, concerned with the testability requirements of your codebase. Separating your application tiers by demarcating with a layer of Spring configuration will be my next approach. This way, I can achieve my provider view using the attractive semantics of Spring bean definitions.