在Moq框架中设置asynchronous任务callback

我有一个接口声明

Task DoSomethingAsync(); 

我正在使用MoqFramework进行testing:

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

然后在我的testing中,我执行调用await DoSomethingAsync()的代码。 而testing只是在这一行失败。 我究竟做错了什么?

你的方法没有任何callback,所以没有理由使用.CallBack() 。 您可以简单地使用.Returns()和Task.FromResult返回一个具有所需值的任务,例如:

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

更新2014-06-22

Moq 4.2有两个新的扩展方法来协助这个。

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

更新2016-05-05

由于Seth Flowers在另一个答案中提到, ReturnsAsync仅适用于返回Task<T> 。 对于只返回任务的方法,

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

可以使用。

如这个答案所示,在.NET 4.6中,这被简化为.Returns(Task.CompletedTask); ,例如:

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

类似的问题

我有一个接口,大致看起来像:

 Task DoSomething(int arg); 

症状

当我的待测服务awaited DoSomething的呼叫时,我的unit testing失败。

固定

与接受的答案不同,在这种情况下,您无法在此方法的Setup()方法上调用.ReturnsAsync()方法,因为该方法返回非通用Task ,而不是Task<T>

但是,您仍然可以在设置上使用.Returns(Task.FromResult(default(object))) ,允许testing通过。

你只需要添加.Returns(Task.FromResult(0)); 回拨后。

例:

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