Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq ReturnsAsync() with no parameters

I use Moq. I have mocked a class which has method that looks like following:

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

I setup it like below:

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

I don't like last line: .Returns(Task.FromResult(default(int))). Is there a way to setup async return in more elegant way. I know there is a method ReturnsAsync() but it has a parameter. My method returns just Task so I don't have a parameter for ReturnsAsync().

like image 206
Артур Габдрахманов Avatar asked Dec 04 '14 13:12

Артур Габдрахманов


1 Answers

Try doing the following:

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

Note that Task.CompletedTask only exists in .NET 4.6 (which was released very recently) or newer. You can find more information in this StackOverflow answer.

ReturnsAsync is for use when you are returning a value asynchronously. When you are returning just a Task, you are not actually returning any asynchronous value at all, so ReturnsAsync doesn't really 'fit' here.

If this doesn't suit your needs, you will have to use Task.FromResult(), unfortunately. As far as I know this is really the only way to create a 'completed' task - aside from perhaps new Task(() => {}) (although this isn't really a completed task, more than a task that completes instantly when awaited) new Task(() => {}) causes a deadlock. Use Task.Run(() => {}).

like image 70
3 revs Avatar answered Oct 29 '22 18:10

3 revs