Java tips, observations, bugs and problems from the world of Spring, Weblogic, Oracle, MySQL and many other technologies...

Tuesday, 29 November 2011

Creating Stubs for Legacy Code - Testing Techniques 6

Any one who reads this blog will probably have realised that at present I’m working on a project that contains a whole bunch of legacy code that’s large, expansive, and written without any tests what so ever. In working with this legacy code, there’s been one very badly behaved class that’s all pervasive, which the whole team have tripped over time and time again. In order to protect the guilty, I’ll call it Mr. X although its real name is SitePropertiesManager as it manages the web site’s properties. It’s badly behaved because it:

breaks the single responsibility principal

has uses singleton pattern summarised by a getInstance() factory method,

has an init() method that must be called before any other method,

loads its data using direct access to the database rather than using a DAO,

uses an complex map of maps to store its data,

accesses the file system to cache data returned by the database

has a timer to decide when up update its cache.

was written before generics and has a multitude of superfluous findXXXX() methods.

doesn’t implement an interface,

employs lots of copy and paste programming.

This makes it hard to create stubs when writing unit tests for new code and leaves the legacy code littered with:

SitePropertiesManager propman = SitePropertiesManager.getInstance();

This blog takes a look at ways of dealing with awkward characters and demonstrates how to create stubs for them, whilst negating the effect of the Singleton pattern. As with my previous Testing Techniques blogs, I’m basing my demo code on my Address web app sample1.

In the other blogs in this series, I’ve been demonstrating how to test the AddressService and this blog is no different. In this scenario, however, the AddressService has to load a site property and decide whether or not to return an address, but before we take a look at that I first of all needed the badly written SitePropertiesManager to play with. However, I don’t own that code, so I’ve written a stunt-double version, which breaks as many rules as I can think of. I’m not going to bore you with the details here as all the source code for SitePropertiesManager is available at: git://github.com/roghughe/captaindebug.git

As I said above, in this scenario, the AddressService is using a site property to determine if it’s enabled. If it is, then it’ll send back an address object. I’m also going to pretend that the AddressService is some legacy code that uses the site properties static factory method as shown below:

In taming this type of class, he first thing to do is to stop using getInstance() to get hold and an object, removing it from the above method and to start using dependency injection. There has to be at least one call to getInstance(), but that can go somewhere in the program’s start-up code. In the Spring world, the solution is to wrap a badly behaved class in a Spring FactoryBean implementation, which becomes the sole location of getInstance() in your application - at least for new / enhancement code.

These changes, however, don’t mean that we can write some proper unit tests for AddressService, they just prepare the ground. The next step is to extract an interface for SitePropertiesManager, which is easily achieved using eclipse.