2010-08-04 61 views
34

我有一組測試用例,其中一些預計會拋出異常。正因爲如此,我已經爲這些測試的屬性,以期待像這樣的例外:NUnit預期的例外

[ExpectedException("System.NullReferenceException")] 

當我在本地運行我的測試一切都很好。但是,當我將測試移至運行TeamCity的CI服務器時,所有預期異常的測試都失敗。這是一個已知的錯誤。

我知道還有NUnit提供的Assert.Throws<>Assert.Throws方法。

我的問題是我如何利用這些而不是我目前使用的屬性?

我看了一下週圍的StackOverflow並嘗試了幾件事情,其中​​沒有一件似乎適用於我。

是否有簡單的1行解決方案來使用它?

回答

62

我不確定你試過的是什麼給你帶來麻煩,但是你可以簡單地傳入一個lambda作爲Assert.Throws的第一個參數。這裏有一個從通過我的測試之一:

Assert.Throws<ArgumentException>(() => pointStore.Store(new[] { firstPoint })); 

好了,例如可能是一個有點冗長。假設我有一個測試

[Test] 
[ExpectedException("System.NullReferenceException")] 
public void TestFoo() 
{ 
    MyObject o = null; 
    o.Foo(); 
} 

這通常會通過,因爲o.Foo()將提高空引用異常。

然後,您將刪除ExpectedException屬性並將您的呼叫打包到o.Foo()中的Assert.Throws

[Test] 
public void TestFoo() 
{ 
    MyObject o = null; 
    Assert.Throws<NullReferenceException>(() => o.Foo()); 
} 

Assert.Throws「試圖調用一個代碼段,表示爲代表,以驗證它拋出一個特定的異常」。 () => DoSomething()語法代表lambda,實質上是一種匿名方法。所以在這種情況下,我們告訴Assert.Throws執行片段o.Foo()

所以不,你不只是像你做一個屬性一樣添加一行;您需要在調用Assert.Throws時明確地包裝將引發異常的測試部分。你不需要必然必須使用拉姆達,但這往往是最方便的。

+0

我不確定這是什麼()=> pointStore.Store(new [] {firstPoint})。是否沒有可以放入我的測試功能的單行? – Martin 2010-08-04 16:51:00

+0

感謝您的額外信息馬克,你幫助讓我真的很清楚,謝謝! – Martin 2010-08-04 21:48:33

+0

謝謝!它解決了我的問題。另外,如果o.Foo是可以等待的,你應該使用'Assert.Throws (async()=> await o.Foo())'。 – CrazyRussianCoder 2015-09-30 16:39:53

6

下面是一個簡單的例子,使用兩種方式。

string test = null; 
Assert.Throws(typeof(NullReferenceException),() => test.Substring(0, 4)); 
Assert.Throws<NullReferenceException>(() => test.Substring(0, 4)); 

如果你不想使用lambdas。

[Test] 
public void Test() 
{ 
    Assert.Throws<NullReferenceException>(_TestBody); 
} 

private void _TestBody() 
{ 
    string test = null; 
    test.Substring(0, 4); 
} 
2

默認情況下,TeamCity使用NUnit 2.2.10,它沒有ExpectedException。查看TeamCity的「NUnit for NAnt」文檔,瞭解如何將其更改爲更現代化的內容,包括TeamCity提供的特定發佈列表。