如何测试私有静态泛型方法? 内部结构对我的测试项目是可见的。 如何测试这些方法?
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 来做到这一点。那么,如何才能做到呢?”
终于找到了一种通过谷歌搜索泛型类型测试来做到这一点的方法。 使用对象自身请求该方法,然后运行通用方法调用,最后调用它。
[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);
}
您不应该测试私有方法。因为它们是可以更改的实现细节。您应该测试您的公共接口。
如果您有在覆盖公共接口后未覆盖的私有方法,请删除它们。
通过我的测试,PrivateObject 似乎在静态和泛型方法方面存在问题。 支持布莱恩的回答,这是一个你可以使用(和修改)的方法。
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 = PrivateMethodTester.InvokePrivateMethodWithReturnType(new TestObjectClass("fake", null), "MyPrivateMethodName", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, types, parameters);
这篇文章非常有趣:How to Write Unit Test For Private Static Method in C#
支持上面接受的答案