I am working on converting a body of synchronous asp.net code to .net 4.5 and the new async syntax.
I have a lot of test code that looks like:
var retVal = new Foo(bar,baz); _myMock.Setup(x => x.DoSomething(123)).Returns(retVal);
When I convert the signature of DoSomething from Foo DoSomething()
to async Task<Foo> DoSomething()
, all of my test code has to be rewritten. My current workaround is to convert the original code to something like:
var retVal = new Foo(bar,baz); _myMock.Setup(x => x.DoSomething(123)) .Returns(new Task<Foo>(()=>retVal));
This is not a particularly hard transform, but it is tedious when I have thousands of tests that need to be updated.
I tried making an extension method called ReturnsAsync to do some of that form m, but I was having some type inferrence issues that I couldn't quite nail down. Is there a standard or easier way to convert this kind of mock to handle the async method better?
First, naming: The Task-based Asynchronous Pattern (TAP) says that all methods that are asynchronous and return Task
s should be named ending with Async
. So, your method should be named DoSomethingAsync
.
Second, the constructor of Task
creates a Task
that is not started, you have to Start()
it manually. If your actual DoSomething
method does this too, that again doesn't follow TAP and it means your code won't work well with await
. Instead, you should use Task.Run(() => value)
, or, even better, Task.FromResult(value)
.
Third, it would be better if you showed us your code that didn't work well, so that we could tell you where did you make a mistake.
Now, the body of ReturnsAsync()
extension method is quite simple, but most of the work for me was in figuring out the correct types (especially since I don't know Moq). The code looks like this:
public static class MoqExtensions { public static IReturnsResult<TMock> ReturnsAsync<TMock, TResult>( this IReturns<TMock, Task<TResult>> setup, TResult value) where TMock : class { return setup.Returns(Task.FromResult(value)); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With