Blog moved to Iserialized.com



Note: My blog has been moved to www.iserialized.com
Please update your link!


Monday, March 1, 2010

Unit testing private methods in C# using NUnit and Reflection

Ever had the need to unit test a private method? Ever change a private method to public just to able to write a test for it? You are definitely not alone! A couple of weeks back I had a very interesting discussions with a very good colleague of mine: "What to do if I want to unit test a private method in C#". In this post I will show how you can use NUnit in combination with Reflection to unit test private methods!

Whether unit testing private method is wrong or not, is far bigger discussion which I will not get into details on in this post. Some of the criticism I have met when I started looking into this, was that if I saw the necessity to unit test a private method, it only meant that my design was wrong! I see the point, but I still see many situations where I either of historical or architectural reasons still have the need to write a unit test for a private method.

I could of course change the method to public, but when working on a larger projects with many junior developers, it's easier to force developers to use a class correct if I only expose the necessary methods for the class to work correctly!

The solution I found to this was to write a method that uses Reflection to extract a MethodInfo object, and then invoke on this to execute the method. So to execute a private static method I can write the following method:


   1:  private static object RunStatic(Type classType, string method)
   2:  {
   3:      var methodInfo = classType.GetMethod(method, 
   4:                  BindingFlags.NonPublic | BindingFlags.Static);
   5:      return methodInfo.Invoke(null, null);
   6:  }

Given that I want to unit test the following class:

   1:  class ClassToTest
   2:  {
   3:      private static bool MyTestMethod()
   4:      {
   5:          return true;
   6:      }
   7:  }

Using Reflection I can write a unit test on MyTestMethod even though it is a private method, by using my RunStatic method. Hence me the following unit testing class:

   1:  [TestFixture]
   2:  public class TestClass
   3:  {
   4:      [Test]
   5:      public void TestConcatTheseStrings()
   6:      {            
   7:          var result = (bool) RunStatic(typeof(ClassToTest), "MyTestMethod");
   8:          Assert.True(result);
   9:      }
  10:   
  11:      private static object RunStatic(Type classType, string method)
  12:      {
  13:          var methodInfo = classType.GetMethod(method,
  14:              BindingFlags.NonPublic | BindingFlags.Static);
  15:          return methodInfo.Invoke(null, null);
  16:      }
  17:  }

Once again: This is a work around! Don't kill the messenger ;)

0 kommentarer:

Post a Comment

Blog moved to iserialized.com



Note: My blog has been moved to www.iserialized.com
Please update your link!


 
Blogglisten