Friday, 12 August 2011

Wrapping Java API Classes

The benefits of using TDD to write your code are well known; the idea that you can write simple, independent, repeatable tests that will challenge your class is a lynch pin of today’s software industry. There are those classes, however, in the Java API, usually the ones that have been around for a long time, that are written in such a way as to make testing difficult and the reason this happens is because they don’t implement an interface or communicate with some external resource.

One such example of this kind of class is InetAddress. It’s been around since version 1.0 of the JDK, doesn’t implement any interfaces, has a private constructor, and communicates with your network to obtain host and IP address information. This means that if your code uses this class directly, then in order to test your code, you’ll also need to communicate with your network and this means that for InetAddress to return your test some useful information, then you’ll need some machine or server or whatnot up and running. This just won’t really do as it breaks nearly all the rules of the FIRST acronym.

One way to approach this problem is to use the adaptor pattern to wrap your problem class and expose it’s methods as an interface. Taking the InetAddress class above as an example then an adaptor for this class would look something like this:

For the above UML diagram, the _InetAddress interface defines all the JDK’s InetAddress methods (only here I’ve only shown one for clarity), whilst MyInetAddress implements all the methods. This means that you are now free to write a stubbed implementation of _InetAddress that will return dummy data and allow you to write test code that does not need to communicate with the network.

Finally, it is worth noting that this is not the only way of solving this problem, you could also take a 'mockist' approach and use, for example, easymock class extensions.

No comments: