Moq4: Missing ReturnsExtensions for Methods which returns Task

Created on 1 Jul 2014  路  5Comments  路  Source: moq/moq4

Moq library has extensions in Moq.ReturnsExtensions for mocked methods which returns Task<> but none for the one with simple Task. Can this feature be added to moq library? Here is example implementation.

public static class ReturnsExtensions
{
    public static IReturnsResult<TMock> ReturnsAsync<TMock>(this IReturns<TMock, Task> mock) where TMock : class
    {
        var tcs = new TaskCompletionSource<object>();
        tcs.SetResult(null);

        return mock.Returns(tcs.Task);
    }
}

Most helpful comment

Here's what I've got in our shared tests project:

public static class MoqExtensions
{
    public static IReturnsResult<TMock> ReturnsAsync<TMock>(this IReturns<TMock, Task> mock) where TMock : class
    {
        return mock.Returns(Task.CompletedTask);
    }

    public static IReturnsResult<TMock> ReturnsEmptyAsync<TMock, TResult>(this IReturns<TMock, Task<IReadOnlyCollection<TResult>>> mock) where TMock : class
    {
        return mock.ReturnsAsync(new TResult[0]);
    }

    public static ISetupSequentialResult<Task<IReadOnlyCollection<TResult>>> ReturnsEmptyAsync<TResult>(this ISetupSequentialResult<Task<IReadOnlyCollection<TResult>>> setup)
    {
        return setup.Returns(Task.FromResult((IReadOnlyCollection<TResult>)new TResult[0]));
    }
}

@kzu Worth a pull request?

All 5 comments

Just edit the source online and make a pull request from the same page.

Also here's an alternative implementation:

// pure non-generic Task
var task = Task.Factory.StartNew(() => { });
return mock.Returns(task);

or

// not null result
var tcs = new TaskCompletionSource<bool>();
tcs.SetResult(true);
return mock.Returns(tcs.Task);

You can also just return a Task.Delay(0)

/kzu

Daniel Cazzulino | Team Lead | Xamarin for Visual Studio

On Tue, Jul 1, 2014 at 4:43 PM, Alexander Batishchev <
[email protected]> wrote:

Just edit the source online
https://github.com/Moq/moq4/edit/master/Source/ReturnsExtensions.cs and
make a pull request from the same page.

Also here's an alternative implementation:

// pure non-generic Task
var task = Task.Factory.StartNew(() => { });
return mock.Returns(task);

or

// not null result
var tcs = new TaskCompletionSource();
tcs.SetResult(true);
return mock.Returns(tcs.Task);

Reply to this email directly or view it on GitHub
https://github.com/Moq/moq4/issues/117#issuecomment-47701143.

There is no need for this feature.

In .NET 4.5 you can just use the new members of Task: Task.Delay, Task.FromResult.

In .NET 4.0, you can just install TaskHelpers.Sources, and have the same (even more!) with TaskHelpers.Completed(), TaskHelpers.FromResult() and many more.

To me, something like
.ReturnsAsync()
would be more readable than
.Returns(Task.FromResult<object>(null))

Here's what I've got in our shared tests project:

public static class MoqExtensions
{
    public static IReturnsResult<TMock> ReturnsAsync<TMock>(this IReturns<TMock, Task> mock) where TMock : class
    {
        return mock.Returns(Task.CompletedTask);
    }

    public static IReturnsResult<TMock> ReturnsEmptyAsync<TMock, TResult>(this IReturns<TMock, Task<IReadOnlyCollection<TResult>>> mock) where TMock : class
    {
        return mock.ReturnsAsync(new TResult[0]);
    }

    public static ISetupSequentialResult<Task<IReadOnlyCollection<TResult>>> ReturnsEmptyAsync<TResult>(this ISetupSequentialResult<Task<IReadOnlyCollection<TResult>>> setup)
    {
        return setup.Returns(Task.FromResult((IReadOnlyCollection<TResult>)new TResult[0]));
    }
}

@kzu Worth a pull request?

Was this page helpful?
0 / 5 - 0 ratings