2010-02-19 7 views
5

Tengo una API de clase que tiene una cobertura de código completa y usa DI para burlar toda la lógica en la función de clase principal (Job.Run) que hace todo el trabajo.NMock2.0: ¿cómo rescindir una llamada que no es de interfaz?

Encontré un error en la producción en el que no hacíamos ninguna validación en uno de los campos de entrada de datos.

Así que agregué una función de código auxiliar llamada ValidateFoo() ... Escribí una prueba de unidad contra esta función para Esperar una excepción JobFailed, ejecuté la prueba; falló, obviamente, porque esa función estaba vacía. Agregué la lógica de validación, y ahora pasa la prueba.

Genial, ahora sabemos que la validación funciona. El problema es: ¿cómo escribo la prueba para asegurarme de que ValidateFoo() se llame realmente dentro de Job.Run()? ValidateFoo() es un método privado de la clase de trabajo, por lo que no es una interfaz ...

¿Hay alguna forma de hacerlo con NMock2.0? Sé que TypeMock admite falsificaciones de tipos de interfaz no. Pero cambiar las libretas simuladas en este momento no es una opción. En este punto, si NMock no puede soportarlo, simplemente agregaré la llamada ValidateFoo() al método Run() y probaré las cosas manualmente, lo que obviamente preferiría no hacer teniendo en cuenta que mi método Job.Run() tiene 100% de cobertura en este momento. ¿Algún consejo? Muchas gracias es apreciado.

EDITAR: la otra opción que tengo en mente es simplemente crear una prueba de integración para mi funcionalidad Job.Run (inyectándole implementaciones verdaderas de los objetos compuestos en lugar de simulaciones). Le daré un valor de entrada incorrecto para ese campo y luego validaré que el trabajo falló. Esto funciona y cubre mi prueba, pero en realidad no es una prueba de unidad, sino una prueba de integración que prueba una unidad de funcionalidad ... hmm ..

EDIT2: ¿Hay alguna manera de hacer tihs? Alguien tiene ideas? Tal vez TypeMock, ¿o un mejor diseño?

Respuesta

5

The current version of NMock2 pueden burlarse de los tipos de hormigón (no me acuerdo exactamente qué versión agregaron esto, pero estamos usando la versión 2.1), utilizando la sintaxis sobre todo familiar:

Job job = mockery.NewMock<Job>(MockStyle.Transparent); 
Stub.On(job).Method("ValidateFoo").Will(Return.Value(true)); 

MockStyle.Transparent especifica que cualquier cosa que La implementación subyacente no maneja ni espera, por lo que puede resguardar y establecer las expectativas de los métodos en una instancia que está probando.

Sin embargo, solo puede resguardar y establecer expectativas sobre métodos públicos (y propiedades), que también deben ser virtuales o abstractos. Así que para evitar depender de las pruebas de integración, tiene dos opciones:

  • gane Job.ValidateFoo() pública y virtual.
  • Extraiga la lógica de validación en una nueva clase e inserte una instancia en Job.
1

Dado que todos los privados son todos llamados por métodos públicos (a menos que se confíe en la ejecución del tiempo de ejecución de la reflexión), esos elementos privados se están ejecutando mediante métodos públicos. Esos métodos privados están causando cambios en el objeto más allá de simplemente ejecutar el código, como establecer campos de clase o llamar a otros objetos. Encontraría una forma de obtener esos "resultados" de llamar al método privado. (O burlarse de las cosas que no deberían ejecutarse en los métodos privados.)

No puedo ver la clase bajo prueba.Otro problema que podría estar presionándolo para querer acceder a los métodos privados es que es una clase súper grande con un montón de funcionalidades privadas. Es posible que estas clases deban dividirse en clases más pequeñas, y algunas de esas partes privadas pueden convertirse en públicos más simples.

Cuestiones relacionadas