Frage

Ich bin derzeit auf der Suche nach Möglichkeiten, um automatisierte Tests für ein JAX-RS (Java API für RESTful Web Services) basierten Web-Service.

Ich brauche im Grunde eine Art und Weise ihm bestimmte Eingaben zu senden und zu überprüfen, ob ich die erwarteten Antworten. Ich würde es vorziehen, dies über JUnit zu tun, aber ich bin mir nicht sicher, wie das erreicht werden kann.

Welcher Ansatz verwenden Sie Ihre Web-Dienste zu testen?

Update: Wie entzik darauf hingewiesen, von der Geschäftslogik des Web-Service-Entkopplung ermöglicht es mir, um Unit-Test der Geschäftslogik. Allerdings mag ich auch für den richtigen HTTP-Statuscodes usw. testen.

War es hilfreich?

Lösung

Jersey mit einem großen RESTful-Client-API kommt die Tests einfach Schreibeinheit macht. Siehe die Unit-Tests in den Beispielen, die mit Jersey versenden. Wir verwenden diesen Ansatz die REST-Unterstützung in Apache Camel zu testen, wenn Sie die Testfälle sind hier

Andere Tipps

Sie können versuchen, REST Assured das macht es sehr einfacher REST-Service zu testen und die Antwort in Java (mit JUnit oder TestNG) zu validieren.

Wie James sagte; Es gibt eingebaute in Test-Framework Jersey. Eine einfache Hallo Welt Beispiel kann so aussehen:

pom.xml für Maven Integration. Wenn Sie laufen mvn test. Frameworks beginnen einen Grizzly Container. Sie können Abhängigkeiten über Wechsel Anlegesteg oder tomcat verwenden.

...
<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>
...

ExampleApp.java

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

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

}

HelloWorld.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!";
    }
}

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

Sie können prüfen, diese Beispielanwendung.

Auch wenn es zu spät ist ab dem Zeitpunkt der Frage der Entsendung, dachte, dies für andere nützlich sein könnten, die eine ähnliche Frage haben. Jersey kommt mit einem Rahmen Test der Jersey Test Framework genannt, die Sie Ihren RESTful testen können Web Service, einschließlich der Antwortstatuscodes. Sie können es verwenden, um Ihre Tests auf leichte Container wie Grizzly, Http und / oder EmbeddedGlassFish laufen. Auch könnte der Rahmen verwendet werden, die Tests auf einer regelmäßigen Web-Container wie Tomcat oder Glassfish laufen.

Sie schrieb wahrscheinlich eine Reihe von Java-Code, der Ihre Geschäftslogik implementiert und dann haben Sie den Web-Services-Endpunkt für sie erzeugt werden.

Eine wichtige Sache zu tun ist, um unabhängig Ihre Geschäftslogik zu testen. Da es reiner Java-Code ist kann man das mit regelmäßigen JUnit-Tests tun.

Nun, da die Web-Services Teil ist nur ein Endpunkt, was Sie sicherstellen möchten, dass die erzeugte Sanitär (Stubs, usw.) in Synchronisierung mit Ihrem Java-Code sind. Sie können durch das Schreiben JUnit-Tests tun, dass die die generierten Web-Service-Java-Clients aufrufen. So können Sie wissen, wann Sie Ihre Java-Signaturen ändern, ohne die Web-Services Sachen zu aktualisieren.

Wenn Sie Ihre Web-Service Sanitär automatisch von Ihrem Build-System bei jeder Build erzeugt wird, dann kann es nicht notwendig sein, um die Endpunkte zu testen (es ist alles richtig erzeugt vorausgesetzt). Hängt von Ihrem Niveau der Paranoia.

Ich verwende Apache Httpclient (http://hc.apache.org/) Restful Dienstleistungen zu nennen . Die HTTP-Client-Bibliothek ermöglicht es Ihnen leicht get auszuführen, Post oder was auch immer andere Operation, die Sie benötigen. Wenn Ihr Dienst JAXB verwendet für XML-Bindung, können Sie eine JAXBContext erstellen serialisiert und deserialisiert Ein- und Ausgänge von der HTTP-Anforderung.

Hier finden Sie aktuelle Alchemy Rest Client Generator . Dies kann eine Proxy-Implementierung für Ihre JAX-RS WebService-Klasse mit Jersey-Client hinter der Szene erzeugen. Effektiv werden Sie Sie von Ihrem Unit-Tests WebService Methoden als einfache Java-Methoden aufrufen. Verarbeitet HTTP-Authentifizierung als auch.

Es gibt keine Code-Generierung beteiligt, wenn Sie einfach Tests ausführen müssen, so dass es bequem ist.

Dislclaimer. Ich bin der Autor dieser Bibliothek

  
    

Eine wichtige Sache zu tun ist, um unabhängig Ihre Geschäftslogik zu testen

  

Ich würde davon ausgehen, schon gar nicht, dass die Person, die den JAX-RS-Code geschrieben und Unit-Test sucht die Schnittstelle ist irgendwie aus irgendeinem bizarren, unerklärlichen Grunde, ohne auf die Vorstellung, dass er oder sie kann Einheit testet andere Teile das Programm, einschließlich der Business-Logik-Klassen. Es ist kaum hilfreich, das Offensichtliche zu erklären, und der Punkt wurde wiederholt gemacht, dass die Antworten auch die getestet werden müssen.

Sowohl Jersey und haben Resteasy-Client-Anwendungen und im Fall von Resteasy können Sie die gleichen annoations verwenden (auch kommentierte Schnittstelle ausklammern und die Verwendung auf dem Client und Server-Seite Ihres Tests).

REST nicht, was dieser Service für Sie tun können; REST, was Sie für diesen Dienst tun können.

Halten Sie es einfach. Hier finden Sie aktuelle https://github.com/valid4j/http-matchers , die importiert werden können von Maven Central.

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

Anwendungsbeispiel:

// 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...

Wie ich der Hauptzweck des auther dieses Problems verstehen ist JAX RS Schicht von Unternehmen einer entkoppeln. Und Unit-Test nur die erste. Zwei grundlegende Probleme hier müssen wir lösen:

  1. Ausführen in Test einige Web / Application Server, setzen JAX RS Komponenten in es. Und nur sie.
  2. Mock Business-Services innerhalb JAX RS Komponenten / REST-Schicht.

Die erste ist mit Arquillian gelöst. Die zweite ist perfekt beschrieben in arquillican und Mock

Hier ist ein Beispiel für den Code, kann es sich unterscheiden, wenn Sie einen anderen Anwendungsserver verwenden, aber ich hoffe, dass Sie die Grundidee und Vorteile erhalten.

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

Ein paar Anmerkungen:

  1. JAX RS-Konfiguration ohne web.xml wird hier verwendet.
  2. JAX RS-Client verwendet wird, hier
  3. (kein Resteasy / Jersey, sie bequeme API aussetzen)
  4. Wenn der Test beginnt, Arquillian Läufer zu arbeiten beginnt. Hier Sie finden können, wie für Arquillian mit den benötigten Anwendungsserver-Tests konfigurieren.
  5. Abhängig von den gewählten Anwendungsserver, eine URL in der Test wird ein wenig unterscheiden. Ein anderer Port verwendet werden. 8181 ist Eingebettet in meinem Beispiel, die von Glasfischen.

Hoffnung, es hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top