Let's say I have some APM (BeginXxx, EndXxx) pattern async methods (as part of some WCF service proxy i'm calling):
public interface ISomeService
{
IAsyncResult BeginSomeMethod(int num, AsyncCallback callback, object state);
int EndSomeMethod(IAsyncResult ar);
}
My actual code uses uses the Task.Factory.FromAsync
to create a Task, and then awaiting this task using the new async/await pattern introduced in .net 4.5.
I would like to test my class and thus I need to write a method that receives the mock, begin method, end method and return value and sets up the mock so that it would eventually return the required return value.
example usage:
SetupAsync(mock, mocked => mocked.BeginSomeMethod, mocked=> mocked.EndSomeMethod, 7);
Which will cause an async flow with any int argument to return 7. I cannot seem to figure out how to accomplish such a thing in moq.
First, I recommend that you use the TaskWsdlImportExtension
to create Task
-based asynchronous WCF proxies. VS2012 does this by default, but you have to set it up yourself on VS2010+AsyncCTP. It's easier to unit test against a Task
API.
If you do want to unit test against Begin
/End
, I think the easiest way would be to use Task
-based mocks and expose Begin
/End
endpoints. The [AsyncFactory|AsyncFactory<T>].[ToBegin|ToEnd]
methods in my AsyncEx library provide Begin
/End
method wrappers around a Task
, or you can see Stephen Toub's blog post about writing these kinds of wrappers.
You can get simple already-completed tasks from Task.FromResult
, or you can use the following construct to force an asynchronously-completed task:
Task.Run(async () => { await Task.Yield(); return 7; });
(the Async CTP equivalent would be):
TaskEx.RunEx(async () => { await TaskEx.Yield(); return 7; });
I'm not entirely sure how to tie this into Moq. Again, I suspect a Task
-based API would be easier to mock than Begin
/End
. Begin
/End
has its own special semantics (you have to pass the correct IAsyncResult
, End
must be called exactly once for each Begin
, etc), so there's more stuff to test.
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