Verkenning van het Jersey Test Framework

1. Overzicht

In deze tutorial gaan we het Jersey Test Framework bekijken en zien hoe we het kunnen gebruiken om snel integratietests te schrijven.

Zoals we al hebben gezien in eerdere artikelen, Jersey is een open source framework voor het ontwikkelen van RESTful Web Services. We kunnen meer over Jersey leren in onze inleiding tot het maken van een API met Jersey en Spring-artikel - hier.

2. Applicatie-instellingen

Het Jersey Test Framework is een hulpmiddel om ons te helpen de correcte implementatie van onze server-side componenten te verifiëren. Zoals we later zullen zien, het biedt een snelle en probleemloze manier om integratietests te schrijven en kan heel goed communiceren met onze HTTP API's.

Evenzo werkt het bijna out-of-the-box en is het gemakkelijk te integreren met onze op Maven gebaseerde projecten. Het framework is voornamelijk gebaseerd op JUnit, hoewel het ook met TestNG kan worden gebruikt, waardoor het in bijna alle omgevingen kan worden gebruikt.

In de volgende sectie zullen we zien welke afhankelijkheden we aan onze applicatie moeten toevoegen om het framework te kunnen gebruiken.

2.1. Afhankelijkheden van Maven

Laten we allereerst de kernafhankelijkheid van Jersey Test Framework toevoegen aan onze pom.xml:

 org.glassfish.jersey.test-framework jersey-test-framework-core 2.27 test 

Zoals altijd kunnen we de nieuwste versie van Maven Central krijgen.

Bijna alle Jersey-tests gebruiken de defacto Grizzly-testcontainerfabriek, die we ook moeten toevoegen:

 org.glassfish.jersey.test-framework.providers jersey-test-framework-provider-grizzly2 2.27 test 

Opnieuw kunnen we de laatste versie vinden in Maven Central.

3. Aan de slag

In dit volgende gedeelte bespreken we de basisstappen die nodig zijn om een ​​eenvoudige test te schrijven.

We gaan beginnen met het testen van het simpele Groeten bron op onze server:

@Path ("/ greetings") public class Groeten {@GET @Path ("/ hi") public String getHiGreeting () {return "hi"; }} 

3.1. De test configureren

Laten we nu onze testklasse definiëren:

openbare klasse GreetingsResourceIntegrationTest breidt JerseyTest uit {@Override beschermde applicatie configure () {retourneer nieuwe ResourceConfig (Greetings.class); } // ...} 

We kunnen in het bovenstaande voorbeeld zien dat om een ​​test te ontwikkelen met behulp van het Jersey Test Framework, onze test een subklasse moet hebben JerseyTest.

Vervolgens overschrijven we de configureren methode die een aangepaste bronconfiguratie retourneert voor onze test en alleen de Groeten bron. Dit is natuurlijk de bron die we willen testen.

3.2. Onze eerste test schrijven

Laten we beginnen met het testen van een eenvoudig GET-verzoek van onze begroetings-API:

@Test openbare leegte gegevenGetHiGreeting_whenCorrectRequest_thenResponseIsOkAndContainsHi () {Reactie respons = doel ("/ greetings / hi"). Request () .get (); assertEquals ("Http Response moet 200 zijn:", Status.OK.getStatusCode (), response.getStatus ()); assertEquals ("Http Content-Type zou moeten zijn:", MediaType.TEXT_HTML, response.getHeaderString (HttpHeaders.CONTENT_TYPE)); String content = response.readEntity (String.class); assertEquals ("Inhoud van ressponse is:", "hi", inhoud); } 

Merk op dat we volledige toegang hebben tot het HTTP-antwoord - zodat we dingen kunnen doen zoals het controleren van de statuscode om er zeker van te zijn dat de bewerking daadwerkelijk is gelukt, of werken met de daadwerkelijke hoofdtekst van het antwoord.

Laten we in meer detail uitleggen wat we doen in het bovenstaande voorbeeld:

  1. Stuur een HTTP GET-verzoek naar ‘/ greetings / hi '
  2. Controleer de HTTP-statuscode en de reactiekoppen van het inhoudstype
  3. Test of de inhoud van het antwoord de tekenreeks 'hallo' bevat

4. GET testen om bronnen op te halen

Nu we de basisstappen hebben gezien die nodig zijn bij het maken van tests. Laten we de eenvoudige Fruit API testen die we hebben geïntroduceerd in het uitstekende Jersey MVC Support-artikel.

4.1. Krijg gewone JSON

In het onderstaande voorbeeld werken we met de responsbody als een standaard JSON-string:

@Test openbare leegte gegevenFruitExists_whenSearching_thenResponseContainsFruit () {laatste String json = target ("fruit / zoeken / aardbei"). Request () .get (String.class); assertThat (json, bevatString ("{\" naam \ ": \" aardbei \ ", \" gewicht \ ": 20}")); }

4.2. Krijg Entiteit in plaats van JSON

We kunnen het antwoord ook rechtstreeks toewijzen aan een resource-entiteitsklasse, bijvoorbeeld:

 @Test openbare ongeldig gegevenFruitExists_whenSearching_thenResponseContainsFruitEntity () {final Fruit entity = target ("fruit / search / strawberry"). Request () .get (Fruit.class); assertEquals ("Fruitnaam:", "aardbei", entity.getName ()); assertEquals ("Vruchtgewicht:", Integer.valueOf (20), entity.getWeight ()); }

Deze keer specificeren we het Java-type waarnaar de responsentiteit zal worden geconverteerd in het krijgen methode - een Fruit voorwerp.

5. POST testen om bronnen te maken

Om een ​​nieuwe bron in onze API te maken, zullen we goed gebruik maken van POST-verzoeken. In de volgende sectie zullen we zien hoe u dit deel van onze API kunt testen.

5.1. Post gewone JSON

Laten we beginnen met het plaatsen van een gewone JSON-string om de aanmaak van een nieuwe fruitresource te testen:

@Test openbare ongeldig gegevenCreateFruit_whenJsonIsCorrect_thenResponseCodeIsCreated () {Response response = target ("fruit / created"). Request () .post (Entity.json ("{\" naam \ ": \" aardbei \ ", \" gewicht \ ": 20} ")); assertEquals ("Http Response moet 201 zijn", Status.CREATED.getStatusCode (), response.getStatus ()); assertThat (response.readEntity (String.class), containsString ("Fruit opgeslagen: Fruit [naam: aardbei kleur: null]")); }

In bovenstaand voorbeeld maken we gebruik van de post methode waarvoor een Entiteit object parameter. We gebruiken de handige json methode om een ​​entiteit te maken op basis van de bijbehorende JSON-reeks.

5.2. Entiteit posten in plaats van JSON

Zoals we al hebben gezien met get-verzoeken, kunnen we ook rechtstreeks een resource-entiteitsklasse posten - bijvoorbeeld:

@Test openbare ongeldig gegevenCreateFruit_whenFruitIsInvalid_thenResponseCodeIsBadRequest () {Fruit fruit = nieuw fruit ("Blueberry", "paars"); fruit.setWeight (1); Antwoordantwoord = target ("fruit / create"). Request (MediaType.APPLICATION_JSON_TYPE) .post (Entity.entity (fruit, MediaType.APPLICATION_JSON_TYPE)); assertEquals ("Http Response moet 400 zijn", 400, response.getStatus ()); assertThat (response.readEntity (String.class), containsString ("Vruchtgewicht moet 10 of hoger zijn")); }

Deze keer gebruiken we de entiteit methode om onze Fruit-entiteit te posten en ook het mediatype op te geven als JSON.

5.3. Formulierinzendingen met behulp van POST

In ons laatste voorbeeld van een bericht zullen we zien hoe we formulierinzendingen kunnen testen via een postverzoek:

@Test openbare leegte gegevenCreateFruit_whenFormContainsNullParam_thenResponseCodeIsBadRequest () {Form form = new Form (); form.param ("naam", "appel"); form.param ("kleur", null); Antwoordantwoord = target ("fruit / create"). Request (MediaType.APPLICATION_FORM_URLENCODED) .post (Entity.form (formulier)); assertEquals ("Http Response moet 400 zijn", 400, response.getStatus ()); assertThat (response.readEntity (String.class), containsString ("Fruit kleur mag niet null zijn")); }

Evenzo maken we gebruik van de Entiteit class, maar geef deze keer een formulier met een aantal parameters door aan ons postverzoek.

6. Testen van andere HTTP-werkwoorden

Soms moeten we andere HTTP-eindpunten testen, zoals PUT en DELETE. Met het Jersey Test Framework is dat natuurlijk perfect mogelijk.

Laten we een eenvoudig PUT-voorbeeld bekijken:

@Test openbare leegte gegevenUpdateFruit_whenFormContainsBadSerialParam_thenResponseCodeIsBadRequest () {Formulier = nieuw formulier (); form.param ("serieel", "2345-2345"); Antwoordantwoord = target ("fruit / update"). Request (MediaType.APPLICATION_FORM_URLENCODED) .put (Entity.form (formulier)); assertEquals ("Http Response moet 400 zijn", 400, response.getStatus ()); assertThat (response.readEntity (String.class), containsString ("Fruit serienummer is niet geldig")); }

Zodra we de verzoek methode, kunnen we elke HTTP-methode aanroepen op het huidige verzoekobject.

7. Extra functies

Het Jersey-testraamwerk bevat een aantal aanvullende configuratie-eigenschappen die kunnen helpen bij het debuggen en testen.

In het volgende voorbeeld zullen we zien hoe u een functie met een bepaalde naam programmatisch inschakelt:

openbare klasse FruitResourceIntegrationTest breidt JerseyTest uit {@Override beschermde applicatie configure () {enable (TestProperties.LOG_TRAFFIC); inschakelen (TestProperties.DUMP_ENTITY); // ...

Wanneer we onze te testen Jersey-applicatie maken en configureren. We kunnen ook aanvullende eigenschappen inschakelen. In dit geval schakelen we twee logging-eigenschappen in: LOG_TRAFFIC en DUMP_ENTITYdie nuttige aanvullende logboekregistratie- en foutopsporingsinformatie zal bieden tijdens testruns.

8. Ondersteunde containers

Zoals we al hebben vermeld, is Grizzly de defacto-container die wordt gebruikt bij het schrijven van tests met het Jersey Test Framework. Er worden echter een aantal andere containers ondersteund:

  • In-Memory-container
  • HttpServer van Oracle JDK
  • Eenvoudige container (org.simpleframework.http
  • Steigercontainer (org.eclipse.jetty)

Raadpleeg de documentatie hier voor meer informatie over het configureren van deze containers.

9. Conclusie

Samenvattend hebben we in deze tutorial het Jersey Test Framework verkend. Eerst hebben we geïntroduceerd hoe we het Jersey Test Framework moesten configureren en daarna zagen we hoe we een test konden schrijven voor een heel eenvoudige API.

In de volgende sectie hebben we gezien hoe we tests kunnen schrijven voor verschillende GET- en POST API-eindpunten. Ten slotte hebben we gekeken naar enkele extra functies en de containers die het Jersey Test Framework ondersteunt.

Zoals altijd is de volledige broncode van het artikel beschikbaar op GitHub.