2012-01-25 18 views
12

Estoy aprendiendo TDD y actualmente tengo un método que funciona pero pensé que podría intentar reconstruirlo usando TDD.Unidad de escritura Pruebas para el método que consulta la base de datos

El método toma esencialmente 6 parámetros, consulta una base de datos, hace un poco de lógica y devuelve un List<T>

Mis pruebas iniciales incluido el control de vacío/valores de los parámetros de cuerda y método int definidos cero, pero ahora no estoy seguro de lo que hacer. Si no estuviera usando TDD, solo crearía código para encontrar la cadena de conexión DB y abriría una conexión DB, consultaría la base de datos, leería los valores, etc.

Obviamente no podemos hacer eso en Pruebas unitarias Estaba buscando algunos consejos sobre cómo proceder.

+5

Nitpick - Si consulta la base de datos, es una prueba de integración, no una prueba de unidad. – Oded

+2

@Oded: es una cuestión de opinión y controversia. –

+1

@Oded - ¡He dicho esa frase tantas veces en el trabajo que es irreal! – Jamiec

Respuesta

9

Recuerde que TDD se trata tanto de un buen diseño como de una prueba. Este método tiene demasiado en marcha; viola el principio de Separación de preocupaciones.

que ya ha identificado varias áreas que deberán ser probados:

El método toma esencialmente 6 parámetros, consulta una base de datos, hace un poco de lógica y devuelve un List<T>

Tienes varios pasos discretos allí, y es probable que haya algunos más escondidos en el código. Romperlos es el nombre del juego cuando se trata de TDD.

Para empezar, puede ser una buena idea factorizar la pieza que realiza la lógica.

¿Está su método construyendo una consulta de forma dinámica? Divida esa pieza también y pruébela para asegurarse de que la consulta esté escrita correctamente.

Puede poner la ejecución de la consulta en un repositorio independiente o algo similar, y escribir pruebas de integración con eso. De esta forma, solo tiene una prueba simple que golpea la base de datos en lugar del método complejo actual.

Si intenta probar esto tal como está, es probable que termine con una prueba de monstruo que requiere mucha configuración y duplica toda la lógica de su negocio, y cuando se rompa, no queda claro qué fue incorrecto.

+0

¿Diría que debería tener un repositorio simulado que simplemente devuelve una lista en la memoria de datos que simula la de las llamadas a la base de datos? – Jon

+0

Exactamente. Y tu lógica puede actuar sobre eso. Esto lo libera de confiar en la base de datos cuando prueba cualquier clasificación/filtrado/procesamiento que esté haciendo. También evita que termine con datos incorrectos en el DB en el futuro que hagan que su prueba "falle"." –

+0

¿Escribo una prueba basada en un nuevo método que devuelve información del DB/MockDB o escribo una prueba basada en el método existente para asegurarme de que se devuelve algo al llamar a un nuevo método que devuelve información de DB? – Jon

6

En general, no hay nada "malo" en usar TDD para probar el código de la base de datos. Sin embargo, puede intentar abstraer el código de la base de datos y luego burlarse de él.

+0

¿Se burla para devolver datos de las consultas? – Jon

+0

Sí, casi. Para devolver datos específicos para pruebas específicas. –

1

Es posible que desee intentar mirar DbUnit para ejecutar pruebas unitarias en su capa de acceso a datos. Pone su base de datos en un estado conocido entre ejecuciones de prueba que evitan la corrupción de su base de datos de prueba.

+0

¿Cualquier equivalente .NET? Esta pregunta es .NET específica. –

+0

@DannyVarod Una búsqueda rápida en Google encontró este proyecto: http://dbunit-net.sourceforge.net/ –

+0

Bueno, pero tecnología DAL específica. Mantener un archivo DB de demostración en el control de código fuente, luego copiar y adjuntar sería más flexible. –

1

Puede:

  1. Uso del inicio de clases/prueba para levantar una base de datos en blanco o una copia de la pequeña base de datos con un conjunto conocido de datos.
  2. En el método de prueba, introduzca los datos de la prueba (si la base de datos está vacía), luego realice la consulta y luego compare el resultado con el resultado esperado.
  3. En la limpieza de prueba/clase, quite la base de datos.

Esto prueba su unidad pero algunos lo consideran una "prueba de integración". - El término "prueba de unidad" tiene algún desacuerdo debido a la ambigüedad del término "unidad".

También podría usar un DB en memoria o un DB en proceso para simplificar el entorno de prueba.

4

El método toma esencialmente 6 parámetros, consulta una base de datos, hace cierta lógica y devuelve una lista

Eso parece ser demasiado mucho por un código comprobable unidad !!

Un código de unidad de prueba debería estar haciendo cosas muy específicas y hacerlo en pequeños módulos. Así, en su caso de tener que refactorizar y romper su método en el siguiente de (al menos):

  • datos de consulta de base: envuelto dentro de un DataProvider con una interfaz de respaldo. Y su prueba de unidad se burlaría de esta interfaz.
  • tiene algo de lógica: este es el mejor candidato para una prueba de unidad. Esto debería ser un módulo que solo toma la interfaz del proveedor de datos y hace la lógica y devuelve la lista modificada que usted validará en su prueba de unidad.

Además, recuerde una prueba de unidad debe cubrir al menos tres escenarios para cada módulo comprobable:

  • una prueba positiva
  • una prueba negativa
  • prueba de lanzar una excepción significativa para valores no válidos.

Espero que esto sea útil.

2

Otra opción es iniciar una transacción antes de la prueba y realizar una reversión posterior. De esta manera, las pruebas son independientes, por lo que todavía pueden, de acuerdo con algunas definiciones, considerarse pruebas unitarias.

Al contrario de lo que se menciona en otras respuestas, debe refactorizar el código para obtener un mejor diseño después de que pase la prueba. Luego puede verificar que su refactorización no haya roto nada con solo volver a ejecutar la prueba.

Cuestiones relacionadas