2014-01-21 110 views
161

我有它聲明設置異步任務回調

Task DoSomethingAsync(); 

我使用MoqFramework對我的測試接口:

[TestMethod()] 
public async Task MyAsyncTest() 
{ 
    Mock<ISomeInterface> mock = new Mock<ISomeInterface>(); 
    mock.Setup(arg => arg.DoSomethingAsync()).Callback(() => { <my code here> }); 
    ... 
} 

然後在我的測試中,我執行代碼調用await DoSomethingAsync()。測試只是失敗了。我究竟做錯了什麼?

+4

當你說在該行的測試錯誤,它會產生什麼樣的錯誤? – AlSki

回答

353

您的方法沒有任何回調,所以沒有理由使用.CallBack()。您可以簡單地返回任務用所需的值.Returns()Task.FromResult,例如:

MyType someValue=...; 
mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.FromResult(someValue)); 

更新2014年6月22日

起訂量4.2有兩個新的擴展方法,以幫助這一點。

mock.Setup(arg=>arg.DoSomethingAsync()) 
    .ReturnsAsync(someValue); 

mock.Setup(arg=>arg.DoSomethingAsync())   
    .ThrowsAsync(new InvalidOperationException()); 

更新2016年5月5日

由於賽斯花卉提到在other answerReturnsAsync是僅適用於返回Task<T>方法。對於只返回任務的方法,可以使用

.Returns(Task.FromResult(default(object))) 

this answer所示,在.NET 4.6這簡化爲.Returns(Task.CompletedTask);,例如:

mock.Setup(arg=>arg.DoSomethingAsync())   
    .Returns(Task.CompletedTask); 
+0

它解決了這個問題。謝謝! – Waldemar

+6

.Returns(Task.CompletedTask);那是我的回答 –

+3

ReturnsAsync很棒。 – Sully

28

類似問題

我有看上去大致等的接口:

Task DoSomething(int arg); 

症狀

我的單元測試失敗時,我的服務awaitedDoSomething的電話。

修復

與接受的答案,你是無法呼叫.ReturnsAsync()您在這種情況下該方法的Setup(),因爲該方法返回非通用Task,而不是Task<T>

但是,您仍然可以在設置上使用.Returns(Task.FromResult(default(object))),從而允許測試通過。

+1

只是想到這一點,如果你需要返回一個非通用任務(非.NET 4.6),我會考慮返回Task.Delay(1)作爲返回任務的簡單方法。你也可以通過增加時間參數來模仿工作。 – stevethethread

13

您只需在回撥後添加.Returns(Task.FromResult(0));即可。

例子:

mock.Setup(arg => arg.DoSomethingAsync()) 
    .Callback(() => { <my code here> }) 
    .Returns(Task.FromResult(0));