2013-02-21 53 views
121

我發現,這些似乎是測試的例外情況的主要有兩種方式:使用NUnit Assert.Throws方法或ExpectedException屬性?

Assert.Throws<Exception>(()=>MethodThatThrows()); 

[ExpectedException(typeof(Exception))] 

其中哪些是最好的?一個人比另一個人有優勢嗎?還是僅僅是個人喜好的問題?

+1

一個第三選擇是流暢的風格:'Assert.That( ()=> MethodThatThrows(),Throws.Exception)' – Schneider 2016-10-07 02:37:14

回答

71

第一個允許您測試多個異常,多次調用:

Assert.Throws(()=>MethodThatThrows()); 
Assert.Throws(()=>Method2ThatThrows()); 

第二隻允許您測試每個測試功能的一個例外。

+19

測試應該只測試一個不同的邏輯位,所以不會在同一個單元測試中測試兩個錯誤被認爲是不好的做法? – SamuelDavis 2013-02-22 00:03:55

+5

@SamuelDavis - 一般來說,你不想在同一個測試中測試不同的情況。但是,可能會有一些用於多個'Assert.Throws'的用例。 – 2013-02-22 00:11:57

+2

無論哪種方式,在這裏你都會得到一個異常作爲參數,它允許你在異常中斷言細節。 此外,使用「預期異常」不會保護您在另一個方法調用中引發的相同異常類型。在這裏,你的目標是確切的方法,而不是整個測試。即使你的測試應該調用很少的代碼,但你永遠不會太安全。特別是當代碼變得複雜和/或異常過於通用時。 像「ArgumentNullExceptions」這樣的東西可能會被拋出很多,例如使用ExpectedException可能會很容易丟失。 Assert.Throws不會錯過它。 – 2016-06-02 21:51:41

28

我更喜歡assert.throws,因爲它允許我在拋出異常之後驗證並斷言其他條件。

[Test] 
    [Category("Slow")] 
    public void IsValidLogFileName_nullFileName_ThrowsExcpetion() 
    { 
     // the exception we expect thrown from the IsValidFileName method 
     var ex = Assert.Throws<ArgumentNullException>(() => a.IsValidLogFileName("")); 

     // now we can test the exception itself 
     Assert.That(ex.Message == "Blah"); 

    } 
+0

這是更好的答案之一,你想驗證在拋出異常之後進入錯誤狀態的情況很常見。 – 2016-04-01 05:47:19

226

的主要區別在於:

ExpectedException()屬性使得如果在發生異常在測試方法中的任何地方測試通過。
Assert.Throws()的用法允許指定exact代碼的位置,其中預期有異常。

NUnit 3.0完全放棄對ExpectedException的官方支持。

所以,我絕對傾向於使用Assert.Throws()方法而不是ExpectedException()屬性。

+4

這是迄今爲止正確的答案。順便提一下,Assert.Throws()也會返回異常,如果它們對您有影響,它可以允許額外檢查異常的屬性。 – perfectionist 2015-05-29 18:14:11

+0

最後回答爲什麼我不能得到ExpectedException與版本3一起工作。 – johnyTee 2017-03-20 21:46:00

+1

這裏是鏈接https://github.com/nunit/docs/wiki/Breaking-Changes - 不再支持ExpectedExceptionAttribute。 – Spirit 2017-12-18 16:54:23

9

您也可以強鍵輸入您期待的錯誤(如舊的attrib版本)。

Assert.Throws<System.InvalidOperationException>(() => breakingAction())