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
TaskWsdlImportExtensionto createTask-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 aTaskAPI.If you do want to unit test against
Begin/End, I think the easiest way would be to useTask-based mocks and exposeBegin/Endendpoints. The[AsyncFactory|AsyncFactory<T>].[ToBegin|ToEnd]methods in my AsyncEx library provideBegin/Endmethod wrappers around aTask, 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:(the Async CTP equivalent would be):
I’m not entirely sure how to tie this into Moq. Again, I suspect a
Task-based API would be easier to mock thanBegin/End.Begin/Endhas its own special semantics (you have to pass the correctIAsyncResult,Endmust be called exactly once for eachBegin, etc), so there’s more stuff to test.