example ejemplo asserttrue assertequals junit code-coverage bytecode emma jacoco

junit - assertequals - asserttrue java ejemplo



Faltan las ramas cuando se utiliza assertTrue en lugar de assertNull (3)

En Java / Junit, necesito probar null con algún objeto. Hay una variedad de formas en que puedo probar una condición, pero he estado usando assertTrue para la mayoría de mis pruebas. Cuando compruebo nulls en assertTrue, EclEmma afirma que solo está probando una rama.

Cuando resuelvo la declaración en una variable de forma manual (como establecer el resultado en un booleano y pasarlo a assertTrue), la cobertura del código se considera completa en la afirmación pero no en la línea de inicialización de la variable.

¿Por qué está pasando esto? ¿Está esto relacionado con el código de bytes extra que Java aparentemente agrega como se menciona en http://sourceforge.net/apps/trac/eclemma/wiki/FilteringOptions ? Cualquier solución (además de usar otras declaraciones de afirmación).

assertTrue:

assertTrue( myObject == null ); //1 of 2 branches

assertTrue:

boolean test = (myObject == null); //1 of 2 branches missing assertTrue(test); // complete

assertNull:

assertNull( myObject ) //complete;


El hecho de que Emma trata una expresión condicional como "algo con una rama" para el conteo de cobertura (rama) en mi humilde opinión simplemente parece quebrado. No es una rama condicional.

Podemos discutir más sobre el Assert; si se definió como "arroja una excepción sobre la falla afirmativa", entonces realmente tiene una rama conditonal; si está definido [como creo que lo hago, no soy un experto en Java] como "terminar mi programa al afirmar el fallo", entonces no es realmente una rama. También son oscuras las llamadas a métodos; estas son ramas condicionales en el sentido de que si el método llamado arroja una excepción, el flujo de control no continúa al "resto de la declaración".

Nuestra herramienta de cobertura de prueba de Java obtiene el análisis de cobertura (rama) en dichos condicionales "a la derecha".


Para la mayoría de las expresiones booleanas, el compilador de Java genera ramas adicionales en el código de bytes. JaCoCo produce "cobertura de sucursal" basada en el código de bytes generado, no basado en el código original de Java, y por lo tanto muestra información adicional de cobertura de sucursal para casi cualquier expresión booleana que utilice.

En su código, la expresión booleana que usa es myObject == null .

Para calcular este valor, el compilador de Java genera código presionando los dos argumentos en la pila y luego haciendo un salto condicional para presionar 1 (verdadero) o 0 (falso) en la pila. JaCoCo informa la cobertura de sucursal de este salto condicional.

Por lo tanto, el hecho de que use myObject == null desencadena el comportamiento que describe.

Como algunos otros ejemplos, intente esto:

boolean t = true; boolean f = false; boolean result1 = (t && f) || f; // 3 out of 6 missed. boolean result2 = !t; // 1 out of 2 missed.

Esto puede ser útil si la expresión booleana es, por ejemplo, devuelta por una función, que se usa como condición en una declaración if-then-else en otro lugar. Si bien es principalmente una consecuencia de la forma en que funciona el compilador de Java, ayuda a evaluar la cobertura de condiciones (en lugar de la mera cobertura de sucursales ) del código original de Java.

Esta función no está muy bien documentada, pero aquí hay algunos consejos:

De modo que, de hecho, está relacionado con el código de bytes extra que se genera, pero no con los ejemplos específicos de compilaciones de compiladores de bytes sintéticos para los que están destinadas las opciones de filtrado.

NOTA: La EDITACIÓN principal desde la respuesta inicial fue demasiado suposición. Gracias a @ ira-baxter por una buena y crítica discusión.


Para obtener una cobertura de código 100% en métodos booleanos, haga lo siguiente

Class RecordService{ public boolean doesRecordExist(String id){ return id!=null; } } //Method inside your mock @Test public boolean testDoesRecordExist(){ RecordService recordService = mock(RecordService.class); when(recordService.doesRecordExists()).thenReturn( anyString()).thenReturn(null); }