2012-09-03 131 views
8

可能重複:
How do I test an async method with NUnit, eventually with another framework?如何聲明C#異步方法在單元測試中引發異常?

我想知道的是,我怎麼能斷言異步方法拋出一個異常,在C#單元測試?我能夠在Visual Studio 2012中使用Microsoft.VisualStudio.TestTools.UnitTesting編寫異步單元測試,但尚未弄清楚如何測試異常。我知道xUnit.net也以這種方式支持異步測試方法,儘管我還沒有嘗試過這個框架。

對於我的意思一個例子,以下代碼定義被測系統:

using System; 
using System.Threading.Tasks; 

public class AsyncClass 
{ 
    public AsyncClass() { } 

    public Task<int> GetIntAsync() 
    { 
     throw new NotImplementedException(); 
    } 
}  

此代碼段定義了一個測試TestGetIntAsyncAsyncClass.GetIntAsync。這是我需要在如何實現這一目標GetIntAsync拋出異常的斷言輸入:

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Threading.Tasks; 

[TestClass] 
public class TestAsyncClass 
{ 
    [TestMethod] 
    public async Task TestGetIntAsync() 
    { 
     var obj = new AsyncClass(); 
     // How do I assert that an exception is thrown? 
     var rslt = await obj.GetIntAsync(); 
    } 
} 

隨意聘請多名Visual Studio的一個,如xUnit.net一些其他相關的單元測試框架,如果有必要或你會認爲這是一個更好的選擇。

+0

@JonSkeet不是真的,因爲這是專門關於檢查異常。儘管我現在看到它與Visual Studio框架沒有任何區別。然而,對於xUnit.net,我仍然不確定如何去做。 – aknuds1

+0

@JonSkeet最初我同意了,但現在我不同意。如果這個問題是正確的,因爲微軟的單元測試已經支持異步測試,你對這個問題的答案在這裏並不適用。唯一的問題是重寫測試,以便測試異常。 – hvd

+0

@hvd:在這種情況下,聽起來像這個問題有*無關*與異步 - 當然,給出的答案不依賴於異步部分。 –

回答

9

請嘗試用標記方法:

[ExpectedException(typeof(NotImplementedException))] 
+0

我沒有想到,在這個框架中,異常是通過屬性來聲明的。謝謝! – aknuds1

+0

不客氣! :) –

6

第一種選擇是:

try 
{ 
    await obj.GetIntAsync(); 
    Assert.Fail("No exception was thrown"); 
} 
catch (NotImplementedException e) 
{  
    Assert.Equal("Exception Message Text", e.Message); 
} 

第二個選項是使用預期的異常屬性:

[ExpectedException(typeof(NotImplementedException))] 

第三選擇是請使用Assert.Throws:

Assert.Throws<NotImplementedException>(delegate { obj.GetIntAsync(); }); 
+0

'Assert.IsTrue(true)'的目的是什麼? – svick

+0

@svick:對!我們可以將其刪除:) – CloudyMarble

+1

@svick有些人使用Assert.IsTrue(true)向任何讀取代碼的人指示,代碼中的代碼表示成功(沒有Assert.IsTrue(true),它可能看起來像作者忘了提出聲明) – Rune

2
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Threading.Tasks; 

[TestClass] 
public class TestAsyncClass 
{ 
    [TestMethod] 
    [ExpectedException(typeof(NotImplementedException))] 
    public async Task TestGetIntAsync() 
    { 
     var obj = new AsyncClass(); 
     // How do I assert that an exception is thrown? 
     var rslt = await obj.GetIntAsync(); 
    } 
} 
0

嘗試使用TPL:

[ExpectedException(typeof(NotImplementedException))] 
[TestMethod] 
public void TestGetInt() 
{ 
    TaskFactory.FromAsync(client.BeginGetInt, client.EndGetInt, null, null) 
       .ContinueWith(result => 
        { 
         Assert.IsNotNull(result.Exception); 
        } 
}