86 votes

Tester un service Web JAX-RS ?

Je suis actuellement à la recherche de moyens pour créer des tests automatisés pour un système de gestion de la qualité. JAX-RS (Java API for RESTful Web Services).

J'ai essentiellement besoin d'un moyen de lui envoyer certaines entrées et de vérifier que j'obtiens les réponses attendues. Je préférerais le faire via JUnit, mais je ne suis pas sûr de la façon dont cela peut être réalisé.

Quelle approche utilisez-vous pour tester vos services web ?

Mise à jour : Comme l'a souligné entzik, le fait de découpler le service web de la logique métier me permet de tester unitairement la logique métier. Cependant, je veux également tester les codes d'état HTTP corrects, etc.

6 votes

Bonne question - cependant, je dirais que si vous effectuez des tests via HTTP, il me semble qu'il s'agit de tests d'intégration.

0 votes

Tom. Vous avez tout à fait raison. Nous devrions injecter un émulateur HTTP factice/un conteneur léger pour cela. Dans le monde node.js supertest fait cela. Vous pouvez émuler express.js.

1voto

Alexandr Points 1576

Si je comprends bien, l'objectif principal de l'auteur de cette question est de découpler la couche JAX RS de la couche métier. Et de ne tester que la première. Nous devons résoudre deux problèmes de base ici :

  1. Exécutez en test un serveur web/application, mettez-y des composants JAX RS. dans ce serveur. Et seulement eux.
  2. Services d'entreprise fictifs dans les composants JAX RS et de la couche REST.

La première est résolue avec Arquillian. La seconde est parfaitement décrite dans arquillican et mock

Voici un exemple de code, il peut être différent si vous utilisez un autre serveur d'application, mais j'espère que vous comprendrez l'idée de base et les avantages.

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));
   }
}

Quelques notes :

  1. La configuration de JAX RS sans web.xml est utilisée ici.
  2. Le client RS JAX est utilisé ici (pas de RESTEasy/Jersey, ils exposent une API plus pratique).
  3. Quand le test commence, le runner d'Arquillian commence à travailler. Ici vous pouvez trouver comment configurer les tests pour Arquillian avec le serveur d'application nécessaire.
  4. En fonction du serveur d'application choisi, une url dans le test sera un peu différent. Un autre port peut être utilisé. 8181 est utilisé par Glassfish Embedded dans mon exemple.

J'espère que ça aidera.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X