ISerialized .Net, C#, Scrum and agile software development

11Mar/105

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 ;)

About Paul Eie

My name is Pål Eie (English alias: Paul Eie) I'm an IT consultant working in Stavanger, Norway. My experience spans from AIX to Windows and from embedded C to Uniface, Java, C++ and C#. My blog will involve everything that is related to technology. As long as it might be of interest to either newbies or seniors, I will blog about it! If you find some of my posts about basic old technology, it just means you know more than many of my other readers!
Comments (5) Trackbacks (0)
  1. 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

  2. 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 ;)

  3. “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.

  4. You have tested it and writing form your personal experience or you find some information online?

  5. 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!


Leave a comment


No trackbacks yet.

Blogglisten