Moq ReturnsAsync() без параметров

Я использую Moq. Я издевался над классом, у которого есть метод, который выглядит следующим образом:

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

Я настраиваю его, как показано ниже:

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

Мне не нравится последняя строка: .Returns(Task.FromResult(default(int))). Есть ли способ настроить async return более элегантным способом. Я знаю, что есть метод ReturnsAsync(), но он имеет параметр. Мой метод возвращает только Task, поэтому у меня нет параметра для ReturnsAsync().

Ответ 1

Попробуйте сделать следующее:

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

Обратите внимание, что Task.CompletedTask существует только в .NET 4.6 (который был выпущен совсем недавно) или новее. Вы можете найти более подробную информацию в этом ответе StackOverflow.

ReturnsAsync предназначен для использования, когда вы возвращаете значение асинхронно. Когда вы возвращаете только Task, вы фактически не возвращаете какое-либо асинхронное значение вообще, поэтому ReturnsAsync здесь действительно не подходит.

Если это не подходит для ваших нужд, вам, к сожалению, придется использовать Task.FromResult(). Насколько я знаю, это действительно единственный способ создать "завершенную" задачу - , кроме, возможно, new Task(() => {}) (хотя это не действительно завершенная задача, это больше, чем задача, которая завершается мгновенно, когда ее ждут) new Task(() => {}) вызывает тупик. Используйте Task.Run(() => {}).