2010-08-19 17 views
5

(C#, Servicio WCF, burla de Rhino, MbUnit)que imita sin inyección

he estado escribiendo las pruebas de código ya en su lugar (sí sé que es al revés, pero así es como su funcionó en mi contrato vigente) He hecho un poco de refactorización para admitir burla: inyecciones, agregar interfaces adicionales, etc., lo que ha mejorado el diseño. En general, mi experiencia en pruebas ha ido bien (exponiendo la fragilidad y mejorando el desacoplamiento). Para cualquier objeto he estado creando los burdos dependientes y esto me sienta bien y tiene sentido.

La aplicación esencialmente tiene 4 capas físicas. La base de datos, una capa de repositorio para el acceso a los datos, un servicio WCF que está conectado al repositorio a través de una capa de gestión (o lógica comercial), por lo que desde arriba hacia abajo se ve así;

WCF Managers Repository Base de datos

Testing los gerentes y capa de repositorio ha sido bastante simple, el imitar las dependencias con Rhino Mocks e inyectarlas en la capa bajo prueba como tal.

Mi problema está en probar la capa superior de WCF. Como mi servicio no tiene el constructor que me permita inyectar las dependencias, no estoy seguro de cómo hago para burlarme de una dependencia al probar los métodos públicos (ServiceContracts) en el servicio.

Espero que tenga sentido y cualquier ayuda muy apreciada. Soy consciente de TypeMockIsolator, etc., pero realmente no quiero ir por esa ruta tanto por razones de presupuesto como por otras razones por las que no entraré aquí. Además, estoy seguro de que hay muchos "Stackers" inteligentes que tienen la información que necesito.

Gracias de antemano.

Respuesta

2

¿Hay alguna razón específica no se puede tener un constructor en su servicio?

De lo contrario, puede tener constructores sobrecargados con un cable de constructor predeterminado encima de los valores predeterminados y un constructor parametrizado con sus dependencias. Ahora puede probar el ctor parametrizado y confiar en el ctor predeterminado para crear la instancia en producción.

public MyService() : this(new DefaultDep1(), new DefaultDep2()) 
{ 
} 

public MyService(IDep1 d1, IDep2 d2) 
{ 
} 

Una mejor solución si se utiliza la inyección de dependencia sería el uso de la WCF IInstanceProvider interface para crear la instancia de servicio y proporcionar las dependencias necesarias a través de ese punto de inyección. Se puede encontrar un ejemplo usando Structure Map here.

+0

Gracias que suena como la ruta que necesito bajar. Gracias por el enlace ... muy útil. –

+0

Gracias a todos por su ayuda. Si bien algunas de las respuestas fueron similares ... elegí esta como breve e indica una solución directa al problema. Gracias a todos de nuevo. –

0

Puede hacer que los servicios WCF sean una capa delgada sobre los "gerentes", por lo que tienen poca o ninguna lógica en ellos que requiera pruebas. Entonces no los pruebes y simplemente prueba a los gerentes. Alternativamente, podría lograr un efecto similar al tener otra capa de 'servicio' que contenga la lógica de los servicios, la cual puede ser probada, y hacer que el código WCF real simplemente pase a través de eso.

+0

Ok ... gracias por eso ... Había considerado hacer algo similar, pero estaba tratando de evitar la introducción de una capa. Pero es bueno tenerlo confirmado como una posibilidad. –

0

Nuestro servicio WCF obtiene todas sus dependencias de un objeto Factory, y le damos al servicio un constructor que toma IFactory. Entonces, si queremos escribir una prueba que se burla de una de las dependencias, digamos una IDependencia, solo tenemos que inyectar una fábrica simulada, que está programada para devolver al servicio el objeto IDependency imputado.

+0

¿Tengo razón al decir que estás presentando efectivamente un segundo constructor solo para permitirte configurarlo para la prueba? No digo que no estoy de acuerdo, solo asegurándome de que lo entiendo. –

+0

Sí, no digo que sea genial, es solo lo que usamos y funciona bien. –

+0

También he usado este enfoque para permitir la prueba del código heredado que no fue diseñado para él. Es un poco feo, pero es efectivo. –

0

Si utiliza una inversión de control (IoC), como Unity, AutoFac o Castle Windsor, y un marco de burla (por ejemplo, Moq, NMock, RhinoMocks) esto es bastante simple siempre que tenga el diseño correcto.

Para un buen tutorial sobre cómo hacerlo con RhinoMock y Windsor, echar un vistazo a este artículo de blog - http://ayende.com/Blog/archive/2007/02/10/WCF-Mocking-and-IoC-Oh-MY.aspx

+0

Hola ... y gracias por el artículo (buena lectura), pero creo que no es exactamente lo que estoy buscando. El artículo se refiere a burlarse del servicio. Realmente no quiero burlarme, quiero probarlo, pero tiene dependencias de las que necesito burlarme que no puedo inyectar. (a menos que me haya perdido algo) –

0

Si está utilizando Castle Windsor, eche un vistazo a WCF facility, le permite usar dependencias no predeterminadas e inyectar dependencias en sus servicios, entre otras cosas.

+0

No soy ... pero tengo la sensación de que debería estar mirándolo :). Gracias por el consejo. –

Cuestiones relacionadas