2010-05-20 22 views
6

Si miramos la cobertura de código de nuestras pruebas unitarias, estamos bastante altos. Pero el último% es complicado porque muchos de ellos están captando cosas como las excepciones de bases de datos, que en circunstancias normales simplemente no ocurren. Por ejemplo, el código evita que los campos sean demasiado largos, etc., por lo que las únicas excepciones posibles a la base de datos son si el DB está roto/abajo, o si el esquema se cambia bajo nuestros pies.¿Cuál es la forma correcta de probar áreas en excepciones?

Entonces, ¿la única forma de simular objetos es que se puede lanzar la excepción? Eso parece un poco sin sentido. Tal vez es mejor simplemente aceptar no obtener cobertura de código 100%?

Gracias, Dan

+3

Los últimos puntos porcentuales no suelen valer la pena (excepto, por supuesto, si la característica que implementan es un requisito básico, entonces comenzaste con los puntos de porcentaje incorrectos ;-)). –

+1

El código de manejo de excepciones generalmente está lleno de errores, definitivamente vale la pena probarlo. – Peli

+0

Tengo que estar de acuerdo con Peli, lo estamos haciendo al 100% y encontramos toneladas y toneladas de posibles errores haciendo esto. – roundcrisis

Respuesta

1

Por lo general, al ejecutar excepciones de bajo nivel, como IOException o SQLException en Java, las envuelvo en una excepción que extiende RuntimeException. Siento que probar este comportamiento es bastante importante porque de lo contrario existe la muy desagradable posibilidad de tragar accidentalmente la excepción.

Por lo tanto, recomiendo probarlos, si realmente hace algo cuando se produce una excepción de bajo nivel.

Editar: Ejemplo agregado.

public void store(User user) { 
    try { 
     userDao.store(user); 
    } catch (IOException e) { 
     // Logging, perhaps some logic. 
     throw new ServiceException(e); 
    } 
} 

@Test(expected = ServiceException.class) 
public void Store_Fail() { 
    UserDao userDaoMock = createMock(UserDao.class); 
    User user = // Create test user. 
    userDaoMock.store(user); 
    replay(userDaoMock); 
    userService.store(user); 
    verify(userDaoMock); 
} 

No hay mucho para probar aquí, pero si la lógica requiere para un ServiceException a ser lanzada por qué no probarlo?

+0

Ok. Entonces, ¿cómo pruebas el tuyo? ¿Se burla del error o encuentra la manera de activarlo de alguna manera? – Codek

+0

@Codek Voy con burlas. En ese caso de prueba específico, inyecté un objeto simulado en la clase probada y lo forcé a arrojar una excepción en la llamada probada. No intento causar ningún tipo de error de archivo o de base de datos porque consume mucho tiempo y, a veces, ni siquiera está claro por qué el método arrojaría la excepción marcada. – ponzao

1

Una práctica común cuando un gol de cobertura del 100% se especifica es cubrir la mayor cantidad posible de código de prueba y cubrir los restantes unos porcentajes de revisión de código.

+0

¿No debería estar cubriendo el resto del código mediante la revisión del código también? – Mark

+0

Por supuesto que sí. Pero esta revisión específica tiene como objetivo justificar por qué esa parte del código no se probó y por qué no debería perjudicar no probarla. – mouviciel

+0

Ok bien. Sin embargo, ¿es posible marcar el código como "no cubierto"? Por el momento, no tenemos una forma clara de identificar, a partir del informe de cobertura, qué código ha sido "revisado por el código" y considerado correcto y cuál no? Así que me gustaría llegar a una especie de pseudo cobertura del 100% donde todo el código ha sido probado o revisado. (La herramienta que utilizamos es EclEmma) – Codek

0
¿Así que la única forma de simular objetos es que se puede lanzar la excepción?

Creo que será la manera más fácil, pero también podría hacer un stub (también conocido como un objeto que amplía el objeto real, y obliga a un comportamiento como lanzar una excepción cada vez). O podría usar AOP, pero creo que usar una biblioteca como easymock o jmock va a ser la forma más fácil de hacerlo.

Eso parece un poco inútil. Tal vez es mejor simplemente aceptar no obtener cobertura de código 100%?

Cuando hablo sobre este tema, me gusta cambiar la mentalidad de las personas de preocuparse por un cierto porcentaje de cobertura, y en su lugar utilizar el porcentaje como una herramienta para que sea un mejor desarrollador. Dicho de otra manera, tener 100% de cobertura o 50% de cobertura no necesariamente significa que su código está bien escrito o incluso funcionando, pero usar Cobertura de código como indicador clave cuando está desarrollando un código sobre si ha estado haciendo pruebas, etc. una buena idea.

Mi opinión personal acerca de su pregunta es que si la aplicación es lógica, entonces vale la pena probarla. Entonces, si está atrapando y la excepción y resintonizando falsamente del método, debe tener una prueba para eso. Si está atrapando la excepción y enviándola en otra excepción, debe probar eso. Si está atrapando la excepción y no haciendo nada, entonces debería ser un olor de código que debe corregirse porque eso puede conducir a todo tipo de efectos secundarios inmanejables.

En cuanto a si el 100% no se enoja, diría que sí, no vale la pena. Debe encontrar un buen nivel de comodidad para usted (tal vez 80%, tal vez 90%) y atenerse a él. Pero no lo basaría en los tipos de pruebas (como la lógica de excepciones de prueba), solo debería basarse en la cobertura total y ser visto como un indicador de que no está escribiendo sus pruebas cuando ingresa el código.

Cuestiones relacionadas