Pregunta

Actualmente estoy buscando formas de crear pruebas automatizadas para un JAX-RS Servicio web basado en (Java API para RESTful Web Services).

Básicamente necesito una forma de enviarle ciertas entradas y verificar que obtenga las respuestas esperadas.Preferiría hacer esto a través de JUnit, pero no estoy seguro de cómo se puede lograr.

¿Qué enfoque utiliza para probar sus servicios web?

Actualizar: Como señaló Entzik, desacoplar el servicio web de la lógica empresarial me permite realizar pruebas unitarias de la lógica empresarial.Sin embargo, también quiero probar los códigos de estado HTTP correctos, etc.

¿Fue útil?

Solución

Jersey viene con una excelente API de cliente RESTful que hace que escribir pruebas unitarias sea realmente fácil.Vea las pruebas unitarias en los ejemplos que se envían con Jersey.Usamos este enfoque para probar el soporte REST en Camello apache, si estás interesado el Los casos de prueba están aquí.

Otros consejos

puedes probar Está seguro lo que lo hace muy Sencillo para probar servicios REST y validar la respuesta en Java (usando JUnit o TestNG).

Como dijo James;Hay incorporado marco de prueba para Jersey.Un ejemplo simple de hola mundo puede ser así:

pom.xml para la integración de maven.cuando corres mvn test.Los marcos inician un contenedor grizzly.Puede utilizar jetty o tomcat cambiando las dependencias.

...
<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.16</version>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework</groupId>
    <artifactId>jersey-test-framework-core</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>

  <dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.16</version>
    <scope>test</scope>
  </dependency>
</dependencies>
...

EjemploApp.java

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class ExampleApp extends Application {

}

HolaMundo.java

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/")
public final class HelloWorld {

    @GET
    @Path("/hello")
    @Produces(MediaType.TEXT_PLAIN)
    public String sayHelloWorld() {

        return "Hello World!";
    }
}

HolaMundoTest.java

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import javax.ws.rs.core.Application;
import static org.junit.Assert.assertEquals;

public class HelloWorldTest extends JerseyTest {

    @Test
    public void testSayHello() {

        final String hello = target("hello").request().get(String.class);

        assertEquals("Hello World!", hello);
    }

    @Override
    protected Application configure() {

        return new ResourceConfig(HelloWorld.class);
    }
}

Puedes comprobar este aplicación de muestra.

Aunque es demasiado tarde desde la fecha de publicación de la pregunta, pensé que esto podría ser útil para otras personas que tengan una pregunta similar.Jersey viene con un marco de prueba llamado Marco de prueba de Jersey que le permite probar su servicio web RESTful, incluidos los códigos de estado de respuesta.Puede usarlo para ejecutar sus pruebas en contenedores livianos como Grizzly, HTTPServer y/o EmbeddedGlassFish.Además, el marco podría usarse para ejecutar sus pruebas en un contenedor web normal como GlassFish o Tomcat.

Probablemente escribió algún código Java que implementa su lógica de negocios y luego generó el punto final de los servicios web.

Algo importante que debe hacer es probar de forma independiente su lógica empresarial.Dado que es código Java puro, puede hacerlo con pruebas JUnit regulares.

Ahora, dado que la parte de servicios web es solo un punto final, lo que debe asegurarse es que las tuberías generadas (stubs, etc.) estén sincronizadas con su código Java.Puede hacerlo escribiendo pruebas JUnit que invoquen los clientes Java del servicio web generado.Esto le permitirá saber cuándo cambia sus firmas de Java sin actualizar los servicios web.

Si su sistema de compilación genera automáticamente la plomería de sus servicios web en cada compilación, entonces puede que no sea necesario probar los puntos finales (suponiendo que todo se haya generado correctamente).Depende de tu nivel de paranoia.

yo uso apache Cliente HTTP (http://hc.apache.org/) para llamar a Restful Services.La biblioteca de cliente HTTP le permite realizar fácilmente obtener, publicar o cualquier otra operación que necesite.Si su servicio utiliza JAXB para el enlace xml, puede crear un JAXBContext para serializar y deserializar entradas y salidas de la solicitud HTTP.

Echa un vistazo a Generador de cliente de descanso de Alchemy.Esto puede generar una implementación de proxy para su clase de servicio web JAX-RS utilizando el cliente Jersey detrás de escena.Efectivamente, llamará a sus métodos de servicio web como métodos Java simples de sus pruebas unitarias.También maneja la autenticación http.

No hay que generar código si simplemente necesita ejecutar pruebas, por lo que es conveniente.

Descargo de responsabilidad:Soy el autor de esta biblioteca.

Algo importante que debe hacer es probar de forma independiente su lógica empresarial.

Ciertamente no asumiría que la persona que escribió el código JAX-RS y está buscando realizar una prueba unitaria de la interfaz es de alguna manera, por alguna razón extraña e inexplicable, ajena a la noción de que él o ella puede realizar pruebas unitarias de otras partes del programa. incluyendo clases de lógica de negocios.No sirve de nada afirmar lo obvio y se señaló repetidamente que las respuestas también deben ser probadas.

Tanto Jersey como RESTEasy tienen aplicaciones cliente y, en el caso de RESTEasy, puede usar las mismas anotaciones (incluso descartar la interfaz anotada y usarla en el lado del cliente y del servidor de sus pruebas).

DESCANSE no es lo que este servicio puede hacer por usted;DESCANSA lo que puedes hacer por este servicio.

Mantenlo simple.Mira esto https://github.com/valid4j/http-matchers que se puede importar desde Maven Central.

    <dependency>
        <groupId>org.valid4j</groupId>
        <artifactId>http-matchers</artifactId>
        <version>1.0</version>
    </dependency>

Ejemplo de uso:

// Statically import the library entry point:
import static org.valid4j.matchers.http.HttpResponseMatchers.*;

// Invoke your web service using plain JAX-RS. E.g:
Client client = ClientBuilder.newClient();
Response response = client.target("http://example.org/hello").request("text/plain").get();

// Verify the response
assertThat(response, hasStatus(Status.OK));
assertThat(response, hasHeader("Content-Encoding", equalTo("gzip")));
assertThat(response, hasEntity(equalTo("content")));
// etc...

Según tengo entendido, el objetivo principal del autor de este problema es desacoplar la capa JAX RS de la empresarial.Y prueba unitaria solo la primera.Aquí tenemos dos problemas básicos que resolver:

  1. Ejecute en prueba algunos servidores web/de aplicaciones, coloque los componentes Jax RS en él.Y sólo ellos.
  2. Servicios comerciales simulados dentro de Jax RS Componentes/Capa de descanso.

El primero se soluciona con Arquillian.El segundo está perfectamente descrito en arquilicano y burlado

Aquí hay un ejemplo del código, puede diferir si usa otro servidor de aplicaciones, pero espero que entienda la idea básica y las ventajas.

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.brandmaker.skinning.service.SomeBean;

/**
* Created by alexandr on 31.07.15.
*/
@Path("/entities")
public class RestBean
{
   @Inject
   SomeBean bean;

   @GET
   public String getEntiry()
   {
       return bean.methodToBeMoked();
   }
}

import java.util.Set;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

import com.google.common.collect.Sets;

/**
*/
@ApplicationPath("res")
public class JAXRSConfiguration extends Application
{
   @Override
   public Set<Class<?>> getClasses()
   {
       return Sets.newHashSet(RestBean.class);
   }
}


public class SomeBean
{
   public String methodToBeMoked()
   {
       return "Original";
   }
}

import javax.enterprise.inject.Specializes;

import com.brandmaker.skinning.service.SomeBean;

/**
*/
@Specializes
public class SomeBeanMock extends SomeBean
{
   @Override
   public String methodToBeMoked()
   {
       return "Mocked";
   }
}

@RunWith(Arquillian.class)
public class RestBeanTest
{
   @Deployment
   public static WebArchive createDeployment() {
       WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
               .addClasses(JAXRSConfiguration.class, RestBean.class, SomeBean.class, SomeBeanMock.class)
               .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
       System.out.println(war.toString(true));
       return war;
   }

   @Test
   public void should_create_greeting() {
       Client client = ClientBuilder.newClient();
       WebTarget target = client.target("http://127.0.0.1:8181/test/res/entities");
       //Building the request i.e a GET request to the RESTful Webservice defined
       //by the URI in the WebTarget instance.
       Invocation invocation = target.request().buildGet();
       //Invoking the request to the RESTful API and capturing the Response.
       Response response = invocation.invoke();
       //As we know that this RESTful Webserivce returns the XML data which can be unmarshalled
       //into the instance of Books by using JAXB.
       Assert.assertEquals("Mocked", response.readEntity(String.class));
   }
}

Un par de notas:

  1. Aquí se utiliza la configuración JAX RS sin web.xml.
  2. Aquí se utiliza el cliente JAX RS (no RESTEasy/Jersey, exponen una API más conveniente)
  3. Cuando comienza la prueba, el corredor de Arquillian comienza a funcionar. Aquí Puede encontrar cómo configurar pruebas para Arquillian con el servidor de aplicaciones necesario.
  4. Dependiendo del servidor de aplicaciones elegido, una URL en la prueba diferirá un poco.Se puede utilizar otro puerto.8181 es utilizado por pescado de vidrio incrustado en mi ejemplo.

Espero que te ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top