java - una - Anotaciones de pruebas unitarias
testing en java (2)
En mi opinión, esas anotaciones son aspectos de su clase y no la esencia de la misma, su verdadero propósito, por lo tanto, no deberían someterse a pruebas unitarias. Quizás mañana utilices Spring MVC en lugar de JAX-RS, pero tu clase tendría el mismo comportamiento, por lo que la prueba unitaria debería ser la misma
Me pregunto qué tan profundo debería entrar (unidad) probando mis clases. Como ejemplo, tengo siguiente clase simple.
import javax.annotation.security.PermitAll;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path(value = "ping")
@Singleton
@PermitAll
public class PingRestService {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String pingMethod(){
return "pong";
}
}
Escribí la siguiente prueba unitaria:
import static org.junit.Assert.*;
import java.lang.reflect.Method;
import javax.annotation.security.PermitAll;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.junit.Test;
public class PingRestServiceTest {
PingRestService prs = new PingRestService();
@Test
public void testClassAnnotations(){
assertEquals(3, prs.getClass().getAnnotations().length);
assertTrue(prs.getClass().isAnnotationPresent(PermitAll.class));
assertTrue(prs.getClass().isAnnotationPresent(Singleton.class));
assertTrue(prs.getClass().isAnnotationPresent(Path.class));
assertEquals("ping", prs.getClass().getAnnotation(Path.class).value());
}
@Test
public void testPingMethodAnnotations() throws SecurityException, NoSuchMethodException{
Method method = prs.getClass().getDeclaredMethod("pingMethod");
assertEquals(2, method.getAnnotations().length);
assertTrue(method.isAnnotationPresent(GET.class));
assertTrue(method.isAnnotationPresent(Produces.class));
assertEquals(1, method.getAnnotation(Produces.class).value().length);
assertEquals(MediaType.TEXT_PLAIN, method.getAnnotation(Produces.class).value()[0]);
}
@Test
public void testPingMethod() {
assertEquals("pong", prs.pingMethod());
}
}
¿tiene sentido? ¿O debería solo probar la cadena de retorno ("pong", testPingMethod), omitir todas las pruebas de anotaciones (testClassAnnotaciones, testPingMethodAnnotations)?
Creo que algunas anotaciones son parte de una lógica empresarial (por ejemplo, PermitAll) y, por lo tanto, deben probarse.
La mayoría de las veces se prueba la funcionalidad del código y no la forma en que se implementa. Esto se llama Black Box Testing
(ver: http://en.wikipedia.org/wiki/Black-box_testing ). Al implementar una prueba, debe preguntarse: "¿Cuáles son los posibles valores de entrada de la unidad para evaluar y cuáles son los resultados esperados?" Ahora, en la prueba, llama a su código con los valores de entrada y verifica el resultado con el esperado para asegurarse de que su código se comporte de la manera que lo desee. Con el tiempo, puede optimizar el código sin querer cambiar la funcionalidad. Entonces no deberías necesitar cambiar tu prueba. Pero puede volver a ejecutarlo para asegurarse de que todavía se comporta de la misma manera. Incluso si se implementa de manera diferente. O bien, puede hacer cambios en los detalles de implementación que tienen efectos secundarios a la funcionalidad que ha probado. Además, en este caso no necesita cambiar la prueba, solo necesita volver a ejecutarla. En su caso simple no tiene entrada y una salida estática, por lo que puede simplemente llamar al método y verificar si se devuelve "pong". Pero los casos de la vida real que se prueban rara vez son tan simples.
Editar: Puede ver la seguridad que configura @PermitAll
y la ruta URL que ''@Path'' configura como entradas y también probarlas en una prueba de integración como lo sugirieron ''Boris the Spider'' y ''Avi''. Pero las otras anotaciones son específicas de la implementación.