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