[英]Testing private static generic methods in C#
如何測試私有靜態泛型方法? 內部結構對我的測試項目可見。 如何測試這些方法?
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 來做到這一點。那么,怎么做呢?”
終於找到了一種方法來通過谷歌搜索使用泛型類型進行測試。 使用它自己請求的對象,然后運行 make 通用方法調用並最后調用它。
[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 = PrivateMethod.InvokePrivateMethodWithReturnType(new TestObjectClass("fake", null), "MyPrivateMethodName", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance, types, parameters);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.