Friday, October 10, 2008

Inversion of Control (IoC) and Test-first Development (TFD) seem to be a match made in heaven. For this and other reasons, Spring is my favorite web framework.

It is not as much of a problem when you are developing an application test-first and from scratch, but dependencies in a legacy system can be a nightmare of an obstacle when you need to go back and add features or fix problems using a test-first approach.

I found myself recently stuck in the midst of dependency hell on a legacy application and wishing that I could simply inject mocks and real objects as needed to setup the application in order to get the code covered with tests.

Instead I had to create wedges and leverage points and basically do a bunch of donkey work just to setup the application so that I could test it. This, by the way, is a clear sign that this application has larger dependency problems. So I added a note to the application's "debt list" so that we could discuss this issue in the near future.

The straight forward, declarative nature of the XML based Spring IoC container is an absolute joy to work with as you are iteratively creating tests to "grow" your new application. For instance let's take a look at the following xml snippet from one of my Spring applications:

<bean id="loginForm" class="security.LoginController"/>
<property name="sessionForm" value="true"/>
<property name="commandName" value="loginBean"/>
<property name="commandClass" value="security.LoginBean"/>
<property name="validator" ref="loginValidator"/>
<property name="formView" value="welcome"/>
<property name="successView" value="./jsp/adminmain.jsp"/>
</bean>

<bean id="loginValidator" class="security.test.MockLoginValidator"/>

In this xml snippet you can see that the login controller needs a validator. However, I am focused on setting up the loginForm first so I don't want to concern myself with creating a loginValidator yet. So in my xml I have declared the loginValidator as a mock. By doing so I will let the loginForm dictate what things the loginValidator will need to validate through its interactions with the mock validator. When I am satisfied that the loginForm is sufficiently done I can then easily change my servlet.xml file and replace the mock with the real login validator.

This capability is extremely powerful and flexible. It allows us to focus directly on the code that we are developing for the tests that we have written and it allows us to iteratively and incrementally add capabilities to the system and grow the system organically from our tests.

0 comments:

Subscribe to RSS Feed Follow me on Twitter!