How to unit test private methods in C# using NUnit
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:
private static object RunStatic(Type classType, string method)
{
var methodInfo = classType.GetMethod(method,
BindingFlags.NonPublic | BindingFlags.Static);
return methodInfo.Invoke(null, null);
}
Given that I want to unit test the following class:
class ClassToTest
{
private static bool MyTestMethod()
{
return true;
}
}
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:
[TestFixture]
public class TestClass
{
[Test]
public void TestConcatTheseStrings()
{
var result = (bool) RunStatic(typeof(ClassToTest), "MyTestMethod");
Assert.True(result);
}
private static object RunStatic(Type classType, string method)
{
var methodInfo = classType.GetMethod(method,
BindingFlags.NonPublic | BindingFlags.Static);
return methodInfo.Invoke(null, null);
}
}
Once again: This is a work around! Don't kill the messenger
March 12th, 2010 - 09:03
Reflection is always a good last resort
Having had just the same problem recently (but Visual Studio’s test tool, not NUnit), I found two other ways of doing it.
1- Have Visual Studio generate a private accessor
http://msdn.microsoft.com/en-us/library/ms184807.aspx
2- Defining InternalsVisibleToAttribute as part of the assembly definition
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx
Cheers
March 12th, 2010 - 09:59
I guess I would have solved it somewhat different I had used Visual Studio’s test tool, but what I like about the reflection approach is that I don’t have to change my original file or any configuration to make it work.
But still, it’s rather dirty to read in the reflection approach
April 7th, 2010 - 22:38
“it’s easier to force developers to use a class correct if I only expose the necessary methods for the class to work correctly”
If you want to do this, them force them through an interface.
April 8th, 2010 - 01:36
You have tested it and writing form your personal experience or you find some information online?
April 8th, 2010 - 20:35
This blog post is a direct result of my own experience on this. I have used this in several projects, and I’m very satisfied with the solution!
The unit tests classes become somewhat hard to read, but I’d rather prefer that over not unit testing private methods or worse, changing them to public methods just to be able to test them!