Using .NET reflection to help test legacy code




One thing that has been bugging me a bit lately, is how to handle private methods in legacy code (or even just plain old untested code).  I've always found that when I have to work with legacy code (and 3rd party libraries) that writing tests to confirm your understanding of it is a good thing and helps you become more confident in using that code.  But how do you handle the situation where you are unsure about how a private method will react under specific conditions - this may be when you want to isolate a bug, or purely just want to gain a better understanding of how it was intended to work. 

One option (and probably the best option) is to refactor that code, so that it is much more 'test-friendly', in which case you will most likely remove the need to test that private method, as it will have acceptable test coverage through the public interface of the object.  But in a lot of cases changing the legacy code is a dangerous, time consuming path that may not be feasible in the time/resource frame you have.

In this case, I have found that using .NET reflection to test the private methods useful.  Consider the example below.

    public class LegacyClass
    {
         private void LegacyMethod(......)
         {
                .......
         }
    }

If I am concerned about the behaviour of LegacyMethod(), I can test it as follows:

    [TestFixture]
    public class LegacyClassTests
    {
         [Test]
         public void TestLegacyMethod()
         {
              LegacyClass myLegacyClass = new LegacyClass();

              Type classType = typeof(LegacyClass);

              MethodInfo method = classType.GetMethod("LegacyMethod", BindingFlags.Instance | BindingFlags.NonPublic);

              method.Invoke(myLegacyClass , ...);

              //Asserts etc
         }
    }

           
Testing this way has confirmed my understanding of the code, and allowed me to be sure about the way to go forward when using this class.

Having said all this though, I still haven't convinced myself that this the best solution, and until I'm convinced I will seek an alternative way to go about it.  The fact that it has come to this stage, is proof alone that there are much bigger problems in the design of the system that need addressing.  However, for the time being it gives me a way to verify my understanding of the legacy code, and to code with confidence.



 del.icio.us  Stumbleupon  Technorati  Digg 

 

What did you think of this article?




Trackbacks
Comments
  • No comments exist for this entry.
Leave a comment

 Enter the above security code (required)

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.