2012-06-30 14 views
5

Digamos que tengo un poco de APM (BeginXxx, EndXxx) métodos patrón asincrónicos (como parte de algún proxy de servicio WCF Voy a llamar):Cómo configurar una llamada al método BeginXXX EndXXX con moq?

public interface ISomeService 
{ 
    IAsyncResult BeginSomeMethod(int num, AsyncCallback callback, object state); 
    int EndSomeMethod(IAsyncResult ar); 
} 

utiliza mi código real utiliza el Task.Factory.FromAsync para crear una tarea, y luego esperando esta tarea usando el nuevo patrón async/await introducido en .net 4.5.

Me gustaría probar mi clase y, por lo tanto, necesito escribir un método que reciba el simulacro, el método de inicio, el método final y el valor de retorno, y configure el simulacro para que eventualmente devuelva el valor de retorno requerido.

ejemplo de uso:

SetupAsync(mock, mocked => mocked.BeginSomeMethod, mocked=> mocked.EndSomeMethod, 7); 

los que ocurre un flujo asíncrono con cualquier argumento int para volver 7. Me parece que no puede encontrar la manera de lograr tal cosa en el moq.

Respuesta

6

En primer lugar, le recomiendo que use el TaskWsdlImportExtension para crear los proxies WCF asíncronos basados ​​en Task. VS2012 lo hace de forma predeterminada, pero usted have to set it up yourself en VS2010 + AsyncCTP. Es más fácil probar la unidad contra una API Task.

Si quieres prueba de la unidad contra Begin/End, creo que la forma más fácil sería utilizar Task simulacros basados ​​y exponer Begin/End puntos finales. Los métodos [AsyncFactory|AsyncFactory<T>].[ToBegin|ToEnd] en mi biblioteca AsyncEx proporcionan Begin/End envoltorios de método alrededor de Task, o puede ver Stephen Toub's blog post about writing these kinds of wrappers.

Puede obtener simples tareas completadas ya -desde Task.FromResult, o puede utilizar la construcción siguiente para forzar una tarea completada de forma asíncrona-:

Task.Run(async() => { await Task.Yield(); return 7; }); 

(el equivalente asíncrono CTP sería):

TaskEx.RunEx(async() => { await TaskEx.Yield(); return 7; }); 

No estoy del todo seguro de cómo vincular esto a Moq. De nuevo, sospecho que una API basada en Task sería más fácil de burlar que Begin/End. Begin/End tiene su propia semántica especiales (que tienen que pasar la correcta IAsyncResult, End debe llamarse exactamente una vez por cada Begin, etc), por lo que hay más cosas para probar.

+0

+1 para TaskWsdlImportExtension. –

Cuestiones relacionadas