Wednesday, January 30, 2008

Unit Testing Legacy Code

After my short HTML/CSS intermezzo I'm back to the business logic programming. Even though it was instructive to do web design and presentation logic I'm happy that I can dive into the lower layers now. With this change I can also switch to my preferred way of developing software, which means TDD.

Everyone who ever wanted to do TDD in a code base that was not designed for testability knows how hard it is. The hardest part is certainly to break dependencies so you can unit test a class or method in isolation. In my last project I was involved we had quite a large code base before we started to write unit tests. With the support of Typemock we could work around the untestable pieces and TDD got possible.

Unfortunately I can't use Typemock on my current project. So I have to get back to other techniques that I learned from "Working Effectively with Legacy Code" by Michael Feathers. Here are the techniques I use a lot:

  • Subclass and Override Method. Create a subclass of the class and override the method to break the dependency.
  • Break out Method Object. Perhaps you can't get a method under test. Create a new class with the method under test.
  • Sometimes it's not possible to create an instance of an object because there are too many dependencies. Expose the method under test as a static method so it's easier to test.
  • Expose private Method. To access a private method from your fixture subclass the class and expose the method.
Even though its a little bit more work in comparison of using Typemock I think the use of these techniques results in more readable test code.