Moq使用没有参数的ReturnsAsync()

Арт*_*нов 9 c# unit-testing moq

我用Moq.我已经嘲笑了一个类似于以下方法的类:

public async Task DoSomething()
{
    // do something...
}
Run Code Online (Sandbox Code Playgroud)

我设置如下:

SomeMock.Setup(x => x.DoSomething())
                .Callback(() => ... ))
                .Returns(Task.FromResult(default(int)));
Run Code Online (Sandbox Code Playgroud)

我不喜欢最后一行:.Returns(Task.FromResult(default(int))).有没有办法以更优雅的方式设置异步返回.我知道有一种方法,ReturnsAsync()但它有一个参数.我的方法返回,Task所以我没有参数ReturnsAsync().

Dan*_*try 15

尝试执行以下操作:

someMock.Setup(x => x.DoSomething())
   .Callback(() => {})
   .Returns(Task.CompletedTask);
Run Code Online (Sandbox Code Playgroud)

请注意,Task.CompletedTask仅存在于.NET 4.6(最近发布)或更新版本中.您可以在 StackOverflow答案中找到更多信息.

ReturnsAsync用于异步返回值时使用.当你只返回a时Task,你实际上根本没有返回任何异步值,所以ReturnsAsync这里并不真正"适合".

如果这不符合您的需求,您将不得不使用Task.FromResult().据我所知,这实际上是创建"已完成"任务的唯一方法 - 除了可能new Task(() => {})(尽管这不是一个真正完成的任务,不仅仅是等待时立即完成的任务) new Task(() => {})会导致死锁.使用Task.Run(() => {}).

  • 实际上,等待`new Task(()=> {})`会导致死锁,因为该任务尚未启动,也永远不会启动.`Task.Run(()=> {})`会工作.话虽这么说,我在使用.NET 4.5时仍然更喜欢`Task.FromResult`. (2认同)