2009-11-11 16 views
17

He trabajado con código que tenía la prueba NUnit escrita. Pero, nunca he trabajado con marcos burlones. ¿Qué son? Entiendo la inyección de dependencia y cómo ayuda a mejorar la capacidad de prueba. Quiero decir que todas las dependencias pueden ser burladas mientras se prueban las unidades. Pero, entonces, ¿por qué necesitamos marcos de burla? ¿No podemos simplemente crear objetos simulados y proporcionar dependencias? ¿Me estoy perdiendo de algo? Gracias.¿Por qué necesitamos marcos burlones?

Respuesta

12
  • Se hace la burla fácil
  • Por lo general le permiten expresar comprobables afirmaciones que se refieren a la interacción entre los objetos .

Aquí tienes un ejemplo:

var extension = MockRepository 
    .GenerateMock<IContextExtension<StandardContext>>(); 
    var ctx = new StandardContext(); 
    ctx.AddExtension(extension); 
    extension.AssertWasCalled(
    e=>e.Attach(null), 
    o=>o.Constraints(Is.Equal(ctx))); 

Se puede ver que pongo a prueba explícitamente que el método de la Adjuntar IContextExtension fue llamado y que el parámetro de entrada se dijo objeto de contexto. Haría que mi prueba fallara si eso no sucediera.

2

La única razón para usar una biblioteca de burlas es que hace más fácil la burla.

Claro, puedes hacerlo todo sin la biblioteca, y eso está bien si es simple, pero tan pronto como comienzan a complicarse, las bibliotecas son mucho más fáciles.

Piense en esto en términos de algoritmos de clasificación, seguro que cualquiera puede escribir uno, pero ¿por qué? Si el código ya existe y es fácil de llamar ... ¿por qué no usarlo?

+2

Algunos marcos de burla van un poco más allá de hacerlo todo a mano, como la estática burlona. –

11

Puede crear objetos simulados a mano y usarlos durante la prueba usando marcos de inyección de dependencia ... pero dejar que un marco burlón genere sus objetos falsos para ahorrar tiempo.

Como siempre, si usar el marco agrega demasiada complejidad para ser útil, entonces no lo use.

1

Sin duda puede burlarse de sus dependencias manualmente, pero con un marco de trabajo le quita mucho trabajo tedioso. También las afirmaciones generalmente disponibles hacen que valga la pena aprender.

3

El uso de un marco de burlarse puede ser una solución mucho más ligera y simple para proporcionar simulacros que la creación de un objeto simulado para cada objeto que desee simular.

Por ejemplo, los marcos de burla son especialmente útiles para hacer cosas como verificar que se realizó una llamada (o incluso cuántas veces se realizó esa llamada). Hacer tus propios objetos simulados para comprobar comportamientos como este (aunque el comportamiento de burla es un tema en sí mismo) es tedioso, y otro lugar más para que introduzcas un error.

Consulte Rhino Mocks para ver un ejemplo de cuán poderoso puede ser un marco de burla.

7

A veces, cuando se trabaja con bibliotecas de terceros, o incluso se trabaja con algunos aspectos de .NET Framework, es extremadamente difícil escribir pruebas para algunas situaciones, por ejemplo, un objeto HttpContext o un objeto Sharepoint. La creación de objetos simulados para ellos puede ser muy engorroso, por lo que los marcos burlones se encargan de lo básico para que podamos dedicar nuestro tiempo a enfocarnos en lo que hace que nuestras aplicaciones sean únicas.

3

Los objetos simulados toman el lugar de los objetos grandes/complejos/externos a los que su código necesita acceso para poder ejecutarlos.

son beneficiosos para algunas razones:

  • Sus pruebas están destinadas a ejecutar rápida y fácilmente. Si su código depende de, por ejemplo, una conexión de base de datos, entonces necesita tener una base de datos completamente configurada y poblada ejecutándose para ejecutar sus pruebas. Esto puede ser molesto, por lo que crea un reemplazo - un "simulacro" - del objeto de conexión de base de datos que solo simula la base de datos.

  • Puede controlar exactamente qué salida sale de los objetos de Mock y, por lo tanto, puede usarlos como fuentes de datos controlables para sus pruebas.

  • Puede crear el simulacro antes de crear el objeto real para refinar su interfaz. Esto es útil en el desarrollo basado en pruebas.

0

Marcos de burlas bien hacen que mi vida sea mucho más fácil y menos tediosa, así que puedo dedicar tiempo a escribir códigos. Tomemos, por ejemplo Mockito (en el mundo de Java)

//mock creation 
List mockedList = mock(List.class); 

//using mock object 
mockedList.add("one"); 
mockedList.clear(); 

//verification 
verify(mockedList).add("one"); 
verify(mockedList).clear(); 

//stubbing using built-in anyInt() argument matcher 
when(mockedList.get(anyInt())).thenReturn("element"); 

//stubbing using hamcrest (let's say isValid() returns your own hamcrest matcher): 
when(mockedList.contains(argThat(isValid()))).thenReturn("element"); 

//following prints "element" 
System.out.println(mockedList.get(999)); 

Aunque este es un ejemplo artificial si se reemplaza con List.classMyComplex.class entonces el valor de tener un marco de burla se hace evidente. Podrías escribir el tuyo o prescindir de él, pero ¿por qué querrías seguir ese camino?

0

Primero me di cuenta por qué necesitaba un marco burlón cuando comparé el doblaje de prueba manualmente para un conjunto de pruebas unitarias (cada prueba necesitaba un comportamiento ligeramente diferente, así que estaba creando subclases de un tipo base falso para cada prueba) con usar algo como RhinoMocks o Moq para hacer el mismo trabajo.

En pocas palabras, era mucho más rápido utilizar un marco para generar todos los objetos falsos que necesitaba en lugar de escribir (y depurar) mis propias falsificaciones a mano.

1

Los marcos de burla te permiten aislar las unidades de código que deseas probar de las dependencias de ese código. También le permiten simular diversos comportamientos de las dependencias de su código en un entorno de prueba que podría ser difícil de configurar o reproducir de otro modo.

Por ejemplo, si tengo una clase A que contiene reglas de negocio y lógica que deseo probar, pero esta clase A depende de una clase de acceso a datos, otras clases de negocios, incluso clases de u/i, etc. se puede burlar a las clases para que actúen de cierta manera (o de ninguna manera en el caso de un comportamiento simulado suelto) para probar la lógica dentro de su clase A en función de todas las formas imaginables en que estas otras clases podrían comportarse en un entorno de producción.

Para dar un ejemplo más profundo, supongamos que la clase A invoca un método en una clase de acceso a datos como

public bool IsOrderOnHold(int orderNumber) {} 

luego un simulacro de esa clase de acceso de datos podría ser configurado para devolver cierto cada vez o para devuelve falso cada vez, para probar cómo su clase A responde a tales circunstancias.

+0

bien dicho. La burla permite anular el comportamiento. – j2emanue

1

Yo afirmaría que no. Escribir dobles de prueba no es una tarea grande en 9 de cada 10 ocasiones. La mayoría de las veces se hace de manera casi automática pidiéndole a reafilador que implemente una interfaz para usted y luego solo agrega el pequeño detalle necesario para este doble (porque no están haciendo un montón de lógica y creando estos intrincados dobles de super prueba, ¿verdad?)

"Pero, ¿por qué querría que mi proyecto de prueba se hinchara con un montón de pruebas dobles?", Puede preguntar. Bueno, no deberías. el principio DRY también se aplica a las pruebas. Cree los dobles de prueba GOOD que sean reutilizables y tengan nombres descriptivos. Esto hace que tus pruebas sean más legibles también.

Una cosa que HACE más difícil es usar en exceso las pruebas dobles. Tiendo a estar de acuerdo con Roy Osherove y el Tío Bob, realmente no quieres crear un objeto simulado con alguna configuración especial con tanta frecuencia. Esto es en sí mismo un olor de diseño. Usando un framework es muy fácil usar test doubles con intrincada lógica en casi todas las pruebas y al final encuentras que no has probado realmente tu código de producción, simplemente has probado el horrible monstruo de burlas de frankenstein que contiene se burla de más burlas. Nunca lo harás "accidentalmente" si escribes tus propios dobles.

Por supuesto, alguien señalará que hay momentos en los que "tienes" que usar un marco, no hacerlo sería simple estupidez. Claro, hay casos como ese. Pero probablemente no tengas ese caso. La mayoría de las personas no, y solo por una pequeña parte del código, o el código en sí es realmente malo.

Recomendaría a cualquiera (ESPECIALMENTE un principiante) que se mantenga alejado de los marcos y aprenda a vivir sin ellos, y luego cuando sientan que realmente tienen que utilizar el marco que consideren más adecuado. , pero para entonces será una desición informada y será mucho menos probable que abusen del marco para crear código incorrecto.

Cuestiones relacionadas