Thursday, June 11, 2015

Jersey-Test Framework

Jersey-Test Framework

Hace unas semanas estuve implementando unas pruebas junto con unos compañeros de trabajo (Daniel, Blanca) para unos servicios REST por medio del framework Jersey Test y me ha parecido sencilla su implementación. Aquí les dejo un ejemplo:

Seleccionar el servidor embebido

JerseyTest suporta el despliegue de aplicaciones en varios contenedores. Actualmente Jersey Test provee soporte para Grizzly, In-Memory, JDK (com.sun.net.httpserver.HttpServer), Simple HTTP container (org.simpleframework.http) y Jetty HTTP container (org.eclipse.jetty).

Para este ejemplo vamos a utilizar Grizzly para lo que vamos a agregar la siguiente dependencia:

testCompile(
  ['junit:junit:4.11'], 
  ['org.mockito:mockito-core:1.10.8'],
  ['org.jboss.weld.se:weld-se:2.1.0.CR1'], 
  ['org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:2.17']
 )

Agregar el recurso

Para este ejemplo utilizaremos un recurso sencillo, junto con la injección de un bean por medio de CDI:


import java.util.List;

import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("empleados")
public class EmpleadoResource {
    @Inject
    private EmpleadoBean bean;

    @GET
    @Produces("application/json")
    public List getEmpleados() {
        return bean.getEmpleados();
    }
    
    @PUT
    @Consumes("application/json")
    public int addEmpleado(Empleado empleado) {
        return bean.addEmpleado(empleado);
    }
}
@Stateless
@Interceptors({ AuditingInterceptor.class, StatisticsInterceptor.class })
public class EmpleadoBean {
    @PersistenceContext(unitName = "nominaJpaUnit")
    private EntityManager em;

    public List getEmpleados() {
        List results = new ArrayList();
        return results;
    }

    public int addEmpleado(Empleado empleado) {
        return 23;
    }
}

Implementar la clase de prueba

Hay que heredar de JerseyTest

public class EmpleadosResourceTest extends JerseyTest {

Ahora vamos a proveer la configuración necesaria para el servidor. Iniciamos el contenedor de dependencias (CDI), indicamos el puerto donde será desplegado nuestro recurso e indicamos la colección de recursos a publicar.


public class ConsolaApplication extends ResourceConfig {    
    public ConsolaApplication() {
        super(JacksonFeature.class);
        register(JacksonObjectMapperProvider.class);
        register(EmpleadoResource.class);
    }
}

public class EmpleadosResourceTest extends JerseyTest {
/**
     * Implementación referencia de CDI.
     */
    private Weld weld;
    
    /**
     * Contenedor de dependencias de la aplicación.
     */
    private WeldContainer container;
    
    @Override
    protected Application configure() {
        weld = new Weld();
        container = weld.initialize();
        this.set(TestProperties.CONTAINER_PORT, PUERTOS.SEGUROS.getPort());
        return new ConsolaApplication();
    }

    @Override
    protected void configureClient(ClientConfig config) {
        // Registra los proveedores para la serialización y deserialización a Json. Es necesario tener la dependencia para el proveedor jersey-media-json-jackson
        config.register(JacksonFeature.class);
    }

Aquí les dejo la clase completa:


/**
 * Pruebas para validar el recurso de empleados.
 * @author Clemente Morales Fernández
 * @since Jun 9, 2015
 *
 */
public class EmpleadosResourceTest extends JerseyTest {
    /**
     * Implementación referencia de CDI.
     */
    private Weld weld;
    
    /**
     * Contenedor de dependencias de la aplicación.
     */
    private WeldContainer container;
    
    @Override
    protected Application configure() {
        weld = new Weld();
        container = weld.initialize();
        this.set(TestProperties.CONTAINER_PORT, PUERTOS.SEGUROS.getPort());
        // Clase para la Configuración de recursos de la aplicación, extiende de ResourceConfig
        return new ConsolaApplication();
    }
    
    @Override
    protected void configureClient(ClientConfig config) {
        // Característica usada para registrar los proveedores de Jackson para JSON.
        config.register(JacksonFeature.class);
    }

    @Test
    public void consultaEmpleadosDevuelveEmpleadosActivos() {        
        WebTarget target = target().path("empleados");
        List<Empleado> empleados = target.request().get(new GenericType<List<Empleado>>(){});
        assertEquals(getEmpleadosEsperadosActivos(), empleados);
    }
    
    @Test
    public void agregarEmpleadoValidoDevuelveIdentificadorCreacion() {        
        WebTarget target = target().path("empleados");
        int res = target.request(MediaType.APPLICATION_JSON)
                .put(Entity.entity(getEmpleadoDummy(),
                        MediaType.APPLICATION_JSON),
                        Integer.class);
        assertTrue(res != 0);
    }
    
    private Empleado getEmpleadoDummy() {
        return new Empleado();
    }

    private List getEmpleadosEsperadosActivos() {
        return Collections.emptyList();
    }

    /**
     * Liberar los recursos obtenidos por el contenedor de dependencias.
     */
    @After
    public void after() {
        weld.shutdown();
    }
}

Monday, June 1, 2015

Salmo 23

“El señor es mi pastor, nada me faltará. En lugares de delicados pastos me hará descansar; junto a aguas de reposo me pastoreará. Confortará mi alma; me guiará por sendas de justicia por amor de su nombre. Aunque ande en valle de sombra de muerte, No temeré mal alguno, por que tú estarás conmigo; Tu vara y tu cayado me infundirán aliento. Aderezas mesa delante de mí en presencia de mis angustiadores; Unges mi cabeza con aceite; mi copa está rebosando. Ciertamente el bien y la misericordia me seguirán todos los días de mi vida, Y en la casa del señor moraré por largos días."