Search code examples
c#genericstestingmethodsstatic

Testing private static generic methods in C#


How does one test private static generic methods? The internals are visible to my test project. How can one test these methods?

internal class Foo {

    // Non-static.  This works!
    private T TestThisMethod1<T>(T value) {
        Console.WriteLine("Called TestThisMethod1");
        return value;
    }

    // Static.  Can't get this to work!
    private static T TestThisMethod2<T>(T value) {
        Console.WriteLine("Called TestThisMethod2");
        return value;
    }

    // Static.  Can't get this to work!
    private static void TestThisMethod3<T>(T value) {
        Console.WriteLine("Called TestThisMethod3");
    }

    // Static.  Can't get this to work!
    private static void TestThisMethod4<T, T2>(T value, T2 value2) {
        Console.WriteLine("Called TestThisMethod4");
    }
}

The first example works. It's not static. It's the example from https://msdn.microsoft.com/en-us/library/bb546207.aspx.

[TestMethod]
public void PrivateStaticGenericMethodTest() {

    int value = 40;
    var foo = new Foo();

    // This works.  It's not static though.
    PrivateObject privateObject = new PrivateObject(foo);
    int result1 = (int)privateObject.Invoke("TestThisMethod1", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) });

    // Fails
    int result2 = (int)privateObject.Invoke("TestThisMethod2",  BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) });

    // Fails
    PrivateType privateType = new PrivateType(typeof(Foo));
    int result2_1 = (int)privateType.InvokeStatic("TestThisMethod2", new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) });

    // Fails
    int result2_2 = (int)privateType.InvokeStatic("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic, new Type[] { typeof(int) }, new Object[] { value }, new Type[] { typeof(int) });

    // Stopping here.  I can't even get TestThisMethod2 to work...
}

My purpose in writing is not really to question or debate the merits of testing private methods: That subjected has been debated over and over. More so, my purpose in writing the question is to say "It should be possible to do this using PrivateObject or PrivateType. So, how can it be done?"


Solution

  • Finally found a way to do this with google searching for testing with generic types. Using the object its self request the method then run through the make generic method call and lastly invoke it.

    [TestMethod]
    public void TestMethod2()
    {
        int value = 40;
        var foo = new Foo();
    
        MethodInfo fooMethod = foo.GetType().GetMethod("TestThisMethod2", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance);
        if (fooMethod == null)
        {
            Assert.Fail("Could not find method");
        }
        MethodInfo genericFooMethod = fooMethod.MakeGenericMethod(typeof(int));
        int result1 = (int)genericFooMethod.Invoke(typeof(int), new object[] { value });
    
        Assert.AreEqual(result1, value);
    }