2009-09-26 17 views
8

tengo este método en mi clase de acceso a datos y tengo una prueba de unidad para asegurarme de que funciona correctamente, pero mi prueba no prueba la excepción, por lo que mi pregunta es ¿debo crear una nueva prueba para forzar la excepción? planteado o debería simplemente confiar en que el bloque de captura funcionará bien en caso de una excepción? Vale la pena el esfuerzo ?¿Debería forzar excepciones para probarlas?

aquí es un ejemplo:

public void UpdateProject(Project project) 
    { 
     using (var transaction = _session.BeginTransaction()) 
     { 
      try 
      { 
       _session.Update(project); 
       _session.Flush(); 
       transaction.Commit(); 
      } 
      catch (HibernateException) 
      { 
       transaction.Rollback(); 
       throw; 
      } 
     } 
    } 

Respuesta

11

Idealmente, usted debe tratar de probar cada línea de código que se puede ... Esto significaría obligar a una excepción que se produzca para probar el controlador de excepciones, y asegúrese esto funciona correctamente

En la práctica, siempre habrá algunas líneas de código no cubiertas; sin embargo, forzaría excepciones mediante burlas para probar cualquier controlador de excepción que considere crítico, especialmente, o que posiblemente se produzca en la producción.

+5

Siempre es divertido depurar un problema de producción donde el bloqueo está en el bloque catch – Mark

+2

Si solo está registrando y volviendo a lanzar, no me molestaría. Probablemente. Siempre y cuando estuviera probando el registro en otro lugar. Si está haciendo algo importante, lo haría. – serialhobbyist

+2

Sí, aunque revertir una transacción puede ser (no siempre) un proceso bastante pesado, que creo que debería probarse. En este caso, lo más probable es que lo pruebe. –

3

Puede obtener su sesión para simular una excepción, pero no es necesario probar que funciona una trampa.

No es incorrecto escribir una prueba para verificar que una transacción se retrotraiga si una actualización arroja una excepción, pero a nivel intuitivo creo que esto está llevando demasiado lejos.

Tal vez un caso más elaborado lo justifique.

Como nota adicional, ¿no retrocedería en algún tipo de excepción?

1

Según el nombre de la excepción (HibernateException), creo que no es un caso excepcional. Entonces puede suceder durante el funcionamiento normal. Si ese es el caso, yo haría una prueba que causa la excepción para asegurarme de que se maneje correctamente.

9

En el kernel de Linux, el 80% de los errores en los controladores están en el código de manejo de errores.

El manejo excepcional es la fuente de muchos errores y seguramente debería probar todas las rutas de excepción.

Por supuesto no se puede probar cada línea de código. Pero la estadística dice que los programadores prestan menos atención al manejo de excepciones, por lo que debes probarlos a fondo.

3

Espero que la transacción sea Rollback si se llama a Displose() antes de Commit() por lo tanto, ¿necesita la captura en absoluto?

En cuanto a otros casos, si su captura hace más que solo registrar el problema, creo que debe ser probado en unidades. Sin embargo, no deje que el hecho de que no pueda realizar pruebas unitarias de ganancias le impida realizar algunas pruebas unitarias.

1

Ciertamente probaré cada excepción específica que se atrape y maneje. Al menos tienes alguna ruta de ejecución a través de tu código de manejo que te dará cierta comodidad de que no ocurra nada más extraño cuando/si alguna vez encuentras una excepción de este tipo durante el tiempo de ejecución.

Recuerde, solo necesita probar el código que desea.

1

Espero que pruebes por separado transaction.Rollback() con las pruebas que agotan todas las situaciones posibles que puedas imaginar. Sin embargo, siempre que las pruebas fueran exhaustivas, probablemente no me molestaría en hacer una excepción ya que no hay nada más en el controlador.

4

Éstos son mis reglas para la prueba ideal de comportamiento de falla:

  • Si está utilizando dependencias que pueden lanzar excepciones, entonces debería incluir pruebas de unidad que hacen que sus burla de ellos generan excepciones.
  • Si bajo ciertas condiciones su código arroja una excepción, entonces debe incluir pruebas unitarias que establezcan tales condiciones.

La primera le permite saber lo que su código se comporta como en Error externo, ya menudo conduce a reconsideraciones de qué hacer. En todas las situaciones, es bueno ver lo que realmente sucede. El segundo solo se asegura de mantener lo que promete, en cuanto a los errores que su código debería detectar y considerar excepcionales. No es diferente de probar otras funciones en su código.

Antes de considerar el conjunto de pruebas unitarias completo, se debe echar un vistazo a código-cobertura del código bajo prueba. Para código no trivial, casi siempre hay una forma en la que mi código de código no se cubre, o peor, tiene un comportamiento que no pretendía. Sorprendentemente, la solución es eliminar ese código en lugar de agregar más pruebas. Acaba de dejar atrás el crumble al aletearlo antes.

No necesariamente digo que se debe alcanzar el 100% de cobertura, pero se debe realizar una prueba de unidades impulsada por cobertura de código porque es una forma más visual de comprender y exponer el comportamiento del código que existe. Solo mirarlo puede darle nuevas ideas sobre cómo refactorizar el código para lograr Single Responsibility Principle y Separation of Concerns.

Cuestiones relacionadas