Unit testing private methods

by Mikael Henriksson 8. January 2010 12:54

Sometimes I can’t be bothered about testing the whole shebang. I just want to test what really counts without having to go through mocking external calls just to verify that something returns true.

This is probably not how one should test code but what the helicopter it works.

[Test]
public void Testing_a_private_method()
{
    BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Instance;
    var instance = new SomeInstance();
    Type type = typeof(SomeInstance);
    var para = new SomeParameterClass()
    para.SomeProperty1 = 2;
    para.SomeProperty2 = 1;
    var parameters = new object[] { para };

    MethodInfo method = type.GetMethod("InstanceMethodName", Flags);
    object obj = method.Invoke(instance, parameters);
    Assert.AreEqual(true, Convert.ToBoolean(obj));
}

EDIT: Inspired by Jan Van Ryswyck I decided to add a much cleaner way of doing this using Func<TInput, TOutput>. I recommend you read his post.

[Test]
public void Testing_a_private_method()
{
    var instance = new SomeInstance();
    var para = new SomeParameterClass()
    para.SomeProperty1 = 2;
    para.SomeProperty2 = 1;
    
    var instanceMethodName = (Func< SomeParameterClass, bool>)
    Delegate.CreateDelegate(
		typeof(Func< SomeParameterClass, bool>), instance, "InstanceMethodName"
		);
    Assert.IsTrue(instanceMethodName(para), "This should really return true");
}

Like Jan mentions it does only work for instance methods not static ones but you shouldn’t be creating too many static methods anyway :)

EDIT2: Also worth noting is that Func of course only works for methods that actually return something. If you need to check the values of something that should have been manipulated without the method returning the manipulated value we need to use another Delegate, say hello to Action!

[Test]
public void Testing_a_private_method()
{
    var instance = new SomeInstance();
    var para = new SomeParameterClass()
    para.SomeProperty1 = 2;
    para.SomeProperty2 = 1;
    
    var instanceMethodName = (Action< SomeParameterClass, bool>)
    Delegate.CreateDelegate(
		typeof(Action< SomeParameterClass, bool>), instance, "InstanceMethodName"
		);
    instanceMethodName(para);
    Assert.AreEqual(2, para.SomeProperty2, "Since we set SomeProperty2 to initial value 1 this will throw if it's not been set while InstanceMethodName executed!");
}

Tags:

Testing

blog comments powered by Disqus