Moq ReturnsAsync()无参数

15

我使用Moq。 我已经模拟了一个具有以下方法的类:

public async Task DoSomething()
{
    // do something...
}

我将它设置为以下方式:

SomeMock.Setup(x => x.DoSomething())
                .Callback(() => ... ))
                .Returns(Task.FromResult(default(int)));

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

1个回答

25

尝试以下操作:

someMock.Setup(x => x.DoSomething())
   .Callback(() => {})
   .Returns(Task.CompletedTask);

注意:只有在 .NET 4.6(最近发布的版本)或更新版本中才存在 Task.CompletedTask。你可以在这里 StackOverflow 回答中找到更多信息。

ReturnsAsync 用于异步返回值时使用。当你仅返回一个 Task 时,实际上并没有返回任何异步值,因此 ReturnsAsync 在此处不太适用。

如果这不符合你的需要,你将不得不使用 Task.FromResult()。据我所知,这确实是创建“已完成”任务的唯一方法 - 除了可能的 new Task(() => {})(虽然这不是真正的已完成任务,而是在等待时立即完成的任务)。new Task(() => {}) 会导致死锁。使用 Task.Run(() => {})


2
实际上,等待 new Task(() => {}) 会导致死锁,因为该任务从未启动,也永远不会启动。但是 Task.Run(() => {}) 可以正常工作。话虽如此,当使用 .NET 4.5 时,我仍然更喜欢使用 Task.FromResult - dcastro
1
我发现另一种选择是使用.Returns(Task.Delay(1))。这对我也起作用。 - Артур Габдрахманов
1
它似乎也可以与 Task.FromResult<object>(null) 一起使用。 - Aaron Newton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接