web-dev-qa-db-fra.com

Comment tester un maillot REST service Web?

J'ai écrit un service Web reposant et je dois le tester avec JUnit4. J'ai déjà écrit un client à l'aide de Jersey Client. Mais je veux savoir si je peux tester mon service uniquement avec junit4. Quelqu'un peut-il m'aider avec échantillon au moins. 

Mon service de repos a une méthode d'authentification qui prend le nom d'utilisateur, le mot de passe et renvoie un jeton. 

J'ai écrit test case pour la méthode authenticate. Mais je ne suis pas sûr de savoir comment tester en utilisant l'URL.

public class TestAuthenticate {
    Service service  = new Service();
    String username = "user";
    String password = "password";
    String token;

    @Test(expected = Exception.class)
    public final void testAuthenticateInputs() {
        password = "pass";
        service.authenticate(username, password);
    }

    @Test(expected = Exception.class)
    public final void testAuthenticateException(){
        username = null;
        String token = service.authenticate(username, password);
        assertNotNull(token);
    }

    @Test
    public final void testAuthenticateResult() {
        String token = service.authenticate(username, password);
        assertNotNull(token);
    }
}
16
Jenny

Si vous souhaitez tester à l'aide de l'URL, vous devez démarrer un serveur à partir de votre test. Vous pouvez explicitement démarrer un serveur intégré, ce qui est assez courant pour les tests. Quelque chose comme

public class MyResourceTest {

    public static final String BASE_URI = "http://localhost:8080/api/";
    private HttpServer server;

    @Before
    public void setUp() throws Exception {
        final ResourceConfig rc = new ResourceConfig(Service.class);
        server = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);       
    }

    @After
    public void tearDown() throws Exception {
        server.stop();
    }

    @Test
    public void testService() {
        Client client = ClientBuilder.newClient();
        WebTarget target = client.target(BASE_URI).path("service");
        ...
    }
}

C'est fondamentalement un test d'intégration. Vous démarrez le conteneur Grizzly et chargez une ResourceConfig sur le serveur avec uniquement la classe Service. Bien sûr, vous pouvez ajouter plus de classes à la configuration. Vous pouvez utiliser la "vraie" configuration de ressources si vous le souhaitez.

Le test ci-dessus utilise cette dépendance

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-grizzly2-http</artifactId>
    <version>${jersey2.version}</version>
</dependency>

Une autre option, qui est celle que je préfère, consiste à utiliser le Jersey Test Framework , qui démarrera un conteneur incorporé pour vous. Un test pourrait ressembler davantage à

public class SimpleTest extends JerseyTest {

    @Override
    protected Application configure() {
        return new ResourceConfig(Service.class);
    }

    @Test
    public void test() {
        String hello = target("service").request().get(String.class);
    }
}

Utiliser cette dépendance

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>${jersey2.version}</version>
    <scope>test</scope>
</dependency>

Et le conteneur Grizzly intégré commencera sous le capot, avec votre configuration ResourceConfig. Dans les deux exemples ci-dessus, on suppose que la valeur @Path de la classe Service est service, comme vous pouvez le constater dans les URL de test. 

Quelques ressources

Quelques exemples


METTRE À JOUR

Si vous n'utilisez pas Maven, voici les pots dont vous aurez besoin pour exécuter un conteneur Grizzly intégré pour le Jersey Test Fraemwork

enter image description here

Je cherche habituellement tous mes pots ici . Vous pouvez sélectionner la version et il devrait y avoir un lien dans la page suivante, à télécharger. Vous pouvez utiliser la barre de recherche pour rechercher les autres.

Voici un exemple simple en cours d'exécution, une fois que vous avez tous les pots

import com.Sun.jersey.api.client.WebResource;
import com.Sun.jersey.api.core.DefaultResourceConfig;
import com.Sun.jersey.spi.container.servlet.WebComponent;
import com.Sun.jersey.test.framework.JerseyTest;
import com.Sun.jersey.test.framework.WebAppDescriptor;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import junit.framework.Assert;
import org.junit.Test;

public class SimpleTest extends JerseyTest {

    @Path("service")
    public static class Service {
        @GET
        public String getTest() { return "Hello World!"; }
    }

    public static class AppConfig extends DefaultResourceConfig {
        public AppConfig() {
            super(Service.class);
        }
    }

    @Override
    public WebAppDescriptor configure() {
        return new WebAppDescriptor.Builder()
                .initParam(WebComponent.RESOURCE_CONFIG_CLASS, 
                           AppConfig.class.getName())
                .build();
    }

    @Test
    public void doTest() {
        WebResource resource = resource().path("service");
        String result = resource.get(String.class);
        Assert.assertEquals("Hello World!", result);
        System.out.println(result);
    }
}

Il est fort probable que vous ne disposerez pas des ressources et de ResourceConfig dans la même classe que le test, mais je veux simplement que ce soit simple et visible dans une classe. 

Que vous utilisiez un fichier web.xml ou une sous-classe ResourceConfig (comme indiqué ci-dessus), vous pouvez réduire ce que vous testez en utilisant un ResourceConfig séparé, intégré à la classe de test, comme je l'ai fait. Sinon, si vous utilisez votre classe ResourceConfig normale, vous pouvez simplement la remplacer dans la méthode configure

La méthode configure consiste à construire un fichier web.xml, uniquement en code Java. Vous pouvez voir différentes méthodes dans le WebAppDescriptor.Builder, comme initParam, qui est identique à un <init-param> dans votre code Web xml. Vous pouvez simplement utiliser la chaîne dans les arguments, mais il y a des constantes, comme je l'ai utilisé ci-dessus.

Le @Test correspond à votre test JUnit habituel. Il utilise le client Jersey. Mais au lieu de créer la Client, vous pouvez simplement utiliser la Client préconfigurée en accédant simplement à la méthode resource(), qui renvoie une WebResource. Si vous connaissez le client Jersey, cette classe ne devrait pas vous être nouvelle.

20
Paul Samsotha

Je pense que @peeskillet vous a fourni les conditions préalables nécessaires, c’est-à-dire que vous devez exécuter votre service Web sur un serveur Web intégré. Vous pouvez également vous pencher sur le support de dropwizard ou spring-boot pour le faire facilement.

En ce qui concerne la vérification de la réponse, je vais rester simple et utiliser JUnit & http-matchers (voir https://github.com/valid4j/http-matchers )

0
keyoxy

Jetez un coup d'œil au générateur de client Alchemy rest . Cela peut générer une implémentation de proxy pour votre classe de service Web JAX-RS en utilisant un client jersey derrière la scène. Effectivement, vous appelerez vos méthodes de service Web des méthodes Java simples issues de vos tests unitaires. Gère également l'authentification http.

Il n'y a pas de génération de code nécessaire si vous devez simplement exécuter des tests pour que ce soit pratique.

Demo here installe grizzly et utilise le générateur ci-dessus pour exécuter des tests Junit.

Disclaimer: Je suis l'auteur de cette bibliothèque.

0
Ashish Shinde