在C#中测试私有静态泛型方法

时间:2017-02-02 15:53:45

标签: c# generics testing methods static

如何测试私有静态泛型方法?我的测试项目可以看到内部结构。如何测试这些方法?

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

第一个例子有效。这不是一成不变的。这是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...
}

我的写作目的并非真正质疑或辩论测试私人方法的优点:这种方式一直受到争议。更重要的是,我写这个问题的目的是说“应该可以使用PrivateObject或PrivateType来做到这一点。那么,怎么做呢?”

3 个答案:

答案 0 :(得分:4)

您不应该测试私有方法。因为它们是可以改变的实现细节。你应该测试你的公共接口。

如果您在覆盖公共界面后拥有未涵盖的私有方法,请将其删除。

答案 1 :(得分:2)

最后找到了一种方法来谷歌搜索通用类型的测试。使用自己请求的对象,然后方法运行make泛型方法调用,最后调用它。

auto get_type() -> struct Abstract;

struct Abstract { virtual ~Abstract() = 0; };

using MyType = decltype(get_type());

答案 2 :(得分:0)

通过我的测试,PrivateObject似乎在使用静态和通用方法时遇到问题。小猪支持Brian的答案,这是您可以使用(和修改)的方法。

public static class PrivateMethodTester
{
    public static object InvokePrivateMethodWithReturnType<T>(T testObject, string methodName, BindingFlags flags, Type[] genericTypes, object[] parameters) {
        MethodInfo methodInfo = testObject.GetType().GetMethod(methodName, flags);
        if (methodInfo == null) {
            throw new Exception("Unable to find method.");
        }
        MethodInfo method = methodInfo.MakeGenericMethod(genericTypes);
        return method.Invoke(genericTypes, parameters);
    } 
}

这样称呼:

            Type[] types = new Type[] { typeof(MyGenericType1) };
            var parameters = new object[] { new MyClassParam(), "stringParam" };
            var returnObj = PrivateMethod.InvokePrivateMethodWithReturnType(new TestObjectClass("fake", null), "MyPrivateMethodName", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, types, parameters);