2012-04-25 75 views
1

我們基於列的數據庫的數據字段被映射到DataField類中。在每個數據字段對象上可以調用GetValue<T>()方法。如果T是非法類型,則會拋出異常。我應該在單元測試中通過哪種類型的測試,如果我通過非法類型測試是否會拋出異常?下一個已知的非法類型在我腦海中出現?還是有一種更抽象的方法?爲單元測試創​​建非法參數類的抽象方法

​​

因此,除了那些每個類型,如果他們通過,應該拋出這個異常。所以我需要一種虛擬類型,對吧?

此刻我的單元測試是這樣的:

[Fact] 
public void If_T_is_illegal_type_an_exception_gets_thrown() 
{ 
    _dataField = new DataField(_params); 
    Assert.Throws<Exception>(() => _dataField.GetValue<Type>()); 
} 
+2

非法類型的例子是什麼?這樣做可以被編譯器捕獲,而不是單元測試。 – yamen 2012-04-25 09:30:54

+0

我更新了我的帖子。 – 2012-04-25 09:37:49

回答

2

請記住,單元測試正試圖通過所有代碼路徑來獲得並確保正確的行爲。您應該總共進行6次測試:一種用於5種有效類型中的一種,另一種用於任何其他類型(如您當前所用)覆蓋最終代碼路徑。不知道爲什麼你需要更抽象的東西。如果你打電話GetValue<bool>()你的代碼將調用typeof(T)五次,使5個比較http://msdn.microsoft.com/en-us/library/xhbhezf4(v=vs.100).aspx

+0

好的。我只是認爲有一種標準或默認的類型,代表*「任何其他類型」*。顯式轉換看起來非常好。雖然我們用另一種通用方法將這些對象轉換爲這樣:'(T)_dataField.GetValue ()'。但顯式轉換不適用於'T',因爲它不是編譯時常量,對吧? – 2012-04-25 10:02:23

0

目前:

你可能更願意使用顯式轉換和鑄造,使這成爲一個編譯時間測試,而不是運行時間。然後它將返回boxed布爾值作爲對象。最糟糕的是,這個方法的簽名沒有說明哪些類型是允許的,哪些會拋出異常。我可以撥打GetValue<decimal>()嗎?不知道。如果不允許,我應該嘗試運行時異常。

考慮所需類型創建重載方法:

bool GetBooleanValue() 
decimal GetDecimalValue() 

這恰如其分地描述它可能會返回什麼類型的。裏面沒有長鏈。來電者不會收到對象。而且你將會在沒有問題的情況下對每種方法進行測試。

+0

這不適合我們的項目。我們實際上從DataFields中提取數據到OurUIDataFields。 OurUIDataFields類是通用的。如果我創建重載,我需要通過T切換來調用不同的get方法。我認爲將DataFields重構爲泛型類將是更好的方法。 – 2012-04-25 10:17:48

0

如上所述,每種支持類型和不支持類型的一種測試應該足夠了。

但我做的一點是,異常不是錯誤的唯一預期結果。你如何驗證錯誤是否被記錄?
你有辦法做到這一點嗎?
如果不是,你想/需要一個?

此外,一個完全不請自來的代碼檢查點......爲什麼

if (typeof(T) == typeof(bool)) return ValueBoolean == true; 

,而不是

if (typeof(T) == typeof(bool)) return ValueBoolean; 

艾倫。

+0

我在我的DataField類中創建了一個靜態記錄器的模擬。當調用Log.Error()時,我會捕獲這個調用並在我的單元測試中設置一個bool'errorFired'變量。 '返回ValueBoolean == true':我也認識到了這一點。這種代碼通常通過ReSharper被移除。 – 2012-04-25 10:14:17

+0

聽起來不錯。它沒有在示例代碼中檢查,所以我想我會提到它。 – AlanT 2012-04-25 10:33:51