2011-09-02 61 views
3

應用TDD時,您是否創建了用於驗證參數(ArgumentException,ArgumentNullException,InvalidOperation等)的期望異常的測試,或者僅創建了「已知」的測試異常,例如CustomerDelinquentException?我應該爲參數異常編寫測試嗎?

等於什麼,gethashcode重寫?我將如何測試gethashcode?

感謝

+2

你真的期望得到一個答案,而不是**「它取決於嗎?」**例如,你有多少測試覆蓋率是你的目標? –

回答

5

我總是測試我在方法拋出任何異常,包括ArgumentNullExceptionArgumentException,等我只是覺得這是最好的測試這些,他們是很容易寫。這樣,如果某人曾經有過移除那些警衛,那麼測試就會中斷,你就會知道。

[TestMethod] 
    [ExpectedException(typeof(ArgumentNullException))] 
    public void ToSetOnNullThrows() 
    { 
     List<string> list = null; 
     var target = list.ToHashSet(); 
    } 

至於GetHashCode()Equals()我測試這些以及如果重寫他們。對於GetHashCode()一個簡單的測試是創建兩個等價對象(在散列碼中使用相同的值)並證明兩個對象生成的散列碼是相同的。

[TestMethod] 
    public void GetHashCodeSameKeysAreSameTest() 
    { 
     var key = new CompositeKey<string, int>("A", 13); 
     var otherKey = new CompositeKey<string, int>("A", 13); 

     Assert.AreEqual(key.GetHashCode(), otherKey.GetHashCode()); 
    } 

你可以嘗試測試兩個不相等的對象返回不同的散列碼,但你必須確保你使用的值不是一個簡單的碰撞。這很大程度上取決於您在GetHashCode()中編碼的算法。

[TestMethod] 
    public void GetHashCodeDifferentKeysAreMostLikelyDifferentTest() 
    { 
     var key = new CompositeKey<string, int>("A", 13); 
     var otherKey = new CompositeKey<string, int>("A", 14); 

     Assert.AreNotEqual(key.GetHashCode(), otherKey.GetHashCode()); 
    } 

對於equals()方法測試具有相同的字段兩個等效的對象上的兩個非等價的物體上Equals()false返回true

[TestMethod] 
    public void EqualsTest() 
    { 
     var key = new CompositeKey<string, int>("A", 13); 
     var otherKey = new CompositeKey<string, int>("A", 13); 

     Assert.IsTrue(key.Equals(otherKey)); 
    } 

    [TestMethod] 
    public void NotEqualsTest() 
    { 
     var key = new CompositeKey<string, int>("A", 13); 
     var otherKey = new CompositeKey<string, int>("A", 15); 

     Assert.IsFalse(key.Equals(otherKey)); 
    } 

更好玩,我喜歡的單元測試DateTime依賴的東西太多。這有點難度,但如果方法的行爲取決於DateTime,我仍然想單元測試它們。因此,您可以創建一個DateTime生成器代理,該代理默認返回DateTime.Now,但具有它,以便您可以將生成器設置爲特定DateTime。幫助了很多與覆蓋在我的工作,因爲我在金融業大量的邏輯取決於售前,售後小時,等上...

public class SomeClassThatDependsOnCurrentTime 
{ 
    internal Func<DateTime> NowGenerator { get; set; } 

    public SomeClassThatDependsOnCurrentTime() 
    { 
     // default in constructor to return DateTime.Now 
     NowGenerator =() => DateTime.Now; 
    } 

    public bool IsAfterMarketClose() 
    { 
     // call the generator instead of DateTime.Now directly... 
     return NowGenerator().TimeOfDay > new TimeSpan(16, 0, 0); 
    } 
} 

然後你只需設置一個單元測試注入一個特定的日期時間。

+0

啊,明白了,謝謝! – Marco

+0

+1:我發現考慮在編寫測試用例時該方法應該拋出什麼異常,這經常可以幫助我找出我不會想到的其他情況。 – StriplingWarrior

+0

@Marco:增加了一些例子,如果你喜歡的話,我也可以查看DateTime生成器的一個例子... –

0

如果您的代碼測試參數並拋出異常,那麼是的,您應該測試這些異常。如果不是或另外,你應該用無效的值來測試你的代碼,看看會發生什麼。

你應該測試equals,以及那種測試gethashcode,當你期望兩個對象相等時。

0

是的。不要忘記單元測試也是一種文檔形式。它向使用組件的下一個開發人員或客戶端展示他們所調用的函數或方法的先決條件。

相關問題