2014-01-21 120 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));