場景。語言C#,單元測試使用VS2008單元測試框架UnitTesting Static Classes
我有一個靜態類與靜態構造函數和2個方法。 我有4個測試方法編寫來測試整個班級。 我的靜態構造函數有一些重要的初始化。
現在,如果我運行的所有串聯4個單元測試用例,靜態構造函數將 纔剛剛開始叫。在每個測試用例的結尾,都沒有這樣的東西
調用了靜態析構函數,所以構造函數中的狀態信息也被帶到了 下一個單元測試用例中。這是什麼解決方法。
場景。語言C#,單元測試使用VS2008單元測試框架UnitTesting Static Classes
我有一個靜態類與靜態構造函數和2個方法。 我有4個測試方法編寫來測試整個班級。 我的靜態構造函數有一些重要的初始化。
現在,如果我運行的所有串聯4個單元測試用例,靜態構造函數將 纔剛剛開始叫。在每個測試用例的結尾,都沒有這樣的東西
調用了靜態析構函數,所以構造函數中的狀態信息也被帶到了 下一個單元測試用例中。這是什麼解決方法。
最簡單的解決方案是一個「重置」的方法添加到您的靜態類,這將對破壞它,重建它的等價行爲。
這裏可能有一個有效的原因,你爲什麼要使用靜態類。但是,由於靜態測試不能很好地進行單元測試,因此我通常會搜索替代設計。
好了,你沒有指定你使用哪種語言,但如果有一種方法可以從測試文件中打開你的靜態類,那麼我會假析構函數添加到它,你可以調用後每個測試。這樣,'析構函數'停留在測試類中,並且不在生產代碼中。
你可以使用Typemock's Isolator它能夠嘲諷靜態類的,所以在每一個測試,你可以「定義」怎麼了靜態將經營。
雖然它不是免費的產品。
這聽起來像你試圖測試靜態構造函數。這似乎是一個壞主意。
請考慮將初始化邏輯提取到單獨的(非靜態)類中。
爲了討論方便,假設你的靜態類被稱爲MySingleton,讓我們說你創建一個名爲MyInitializer新的類,它有一個Execute方法。 MySingleton的靜態構造函數可以實例化MyInitializer並調用執行所有初始化的Execute。
然後您的生產代碼可以使用MySingleton,並忽略MyInitializer。另一方面,您的測試可能會忽略MySingleton,並愉快地爲每個測試創建一個新的MyInitializer實例,每次都會重新開始。
不知道類的用法只是用法的評論是有點棘手,但生病反正它反正。對我來說,上述聽起來不僅僅是一個測試問題。
靜態類(就如同單身)基本上都是全局函數/變量的集合,通常是在OOP壞事。我會說,試圖測試測試問題是(儘管現在可能是最簡單的),但只修復症狀而不是問題。
我建議採取看看德興一個concidere如果你真的需要靜態類,或者如果它只是似乎是最簡單的方法在時間來解決問題
我會移動從初始化靜態構造函數指向由構造函數調用的方法。通過使用此方法內部,然後可以從測試中調用此方法以重新初始化類。
public static class MyClass
{
public static MyClass()
{
initialize();
}
internal static void initialize()
{
// Do initialization (and cleanup if necessary)
}
public static void Method1() {}
public static void Method2() {}
}
爲了叫你需要使用InternalsVisibleTo屬性,如this blog描述的內部方法。
您也可以將其設爲私有,但您需要使用反射來調用它。
但正如Andrew Shepherd所說,你還應該檢查靜態類是否是這個類的最佳設計。
Type staticType = typeof(StaticClassName);
ConstructorInfo ci = staticType.TypeInitializer;
object[] parameters = new object[0];
ci.Invoke(null, parameters);
從http://colinmackay.scot/2007/06/16/unit-testing-a-static-class/
爲了完整起見,如果你需要重新設置一個靜態類的非公共字段/變量,還可以通過反射這樣做。
using System.Reflection; // or Mono.Reflection
public static class MyClass{
private static string myString;
}
var newValue = "Potatoes";
var field = typeof(MyClass).GetField("myString", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, newValue); // the first null is because the class is static, the second is the new value
嘿看,這個問題的實際答案,而不是「不這樣做」。 – deltree 2013-04-17 14:18:35