2017-02-02 85 views
0

如何測試私有靜態泛型方法?內部對我的測試項目是可見的。如何測試這些方法?在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來做到這一點,那麼,怎麼做呢?」

+2

你有沒有你的私有靜態方法的消費者?如果不是,那爲什麼要測試它的行爲? –

+7

一般私人方法通過調用它們的公共方法進行測試 –

+0

的確,我通常遵循「僅測試公共方法」的規範。這些天,如果我可以避免的話,我討厭公開使用任何東西。這種方法深埋在代碼中。我應該能夠用PrivateObject或PrivateType隔離測試此方法。 – clarionprogrammer

回答

5

你不應該測試私人方法。因爲它們是可以改變的實現細節。你應該測試你的公共接口。

如果您有隱私公開接口後沒有涵蓋的私有方法,請刪除它們。

+1

我並不總是訂閱一條硬性規定「你不應該測試私人方法。」 假設你有一個只有公共入口點的複雜控制檯應用程序,你會不會測試任何東西?我不想僅僅因爲我想測試它而改變方法的可訪問性。 – clarionprogrammer

+0

如果您的控制檯應用程序不夠模塊化,並且只有它作爲公共入口點的主要應用程序,那麼對於某些不值得爲單元測試編寫的內容而言,它可能是一種快速入侵,或者它是不合標準的軟件設計。控制檯應用程序是UI ...您的業務和數據層不應該是私有方法。 – nvoigt

+0

控制檯應用只是一個例子....我的意圖不是討論測試私有方法的價值。 微軟在創建PrivateObject和PrivateType類來測試私有方法時看到了價值。我正在尋求理解如何正確使用它們。 – clarionprogrammer

2

終於找到了一種方法來做到這一點與谷歌搜索與泛型類型的測試。使用該對象的自我請求方法,然後通過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); 
} 
+0

這是一個解決方案,它確實回答了這個問題。 我期待PrivateObject或PrivateType可以在幕後執行此操作,而無需執行反射。不幸的是,似乎這兩種方法都不適用於這種特殊情況。 – clarionprogrammer