Inleiding tot WireMock

1. Overzicht

WireMock is een bibliotheek voor het stoten en bespotten van webservices. Het construeert een HTTP-server waarmee we verbinding kunnen maken zoals we zouden doen met een echte webservice.

Wanneer een WireMock-server in actie is, kunnen we verwachtingen opstellen, de service bellen en vervolgens zijn gedrag verifiëren.

2. Maven afhankelijkheden

Om te kunnen profiteren van de WireMock-bibliotheek, moeten we de volgende afhankelijkheid in de POM opnemen:

 com.github.tomakehurst wiremock 1.58 test 

3. Programmatisch beheerde server

Dit gedeelte behandelt de manier om handmatig een WireMock-server te configureren. d.w.z. zonder de ondersteuning van de automatische configuratie van JUnit. Het gebruik wordt aangetoond door een zeer eenvoudige stomp.

3.1. Server instellen

Een WireMock-server kan als volgt worden geïnstantieerd:

WireMockServer wireMockServer = nieuwe WireMockServer (String host, int poort);

Als er geen argumenten worden opgegeven, is de serverhost standaard localhost en de serverpoort naar 8080.

De server kan vervolgens worden gestart en gestopt met behulp van twee eenvoudige methoden:

wireMockServer.start ();

En:

wireMockServer.stop ();

3.2. Basisgebruik

De WireMock-bibliotheek zal eerst worden gedemonstreerd door een basisgebruik, waarbij een stomp voor een exacte URL zonder enige verdere configuratie wordt verstrekt. Laten we een serverinstantie maken:

WireMockServer wireMockServer = nieuwe WireMockServer ();

De WireMock-server moet actief zijn voordat de client er verbinding mee maakt:

wireMockServer.start ();

De webservice wordt dan gestopt:

configureFor ("localhost", 8080); stubFor (get (urlEqualTo ("/ baeldung")). willReturn (aResponse (). withBody ("Welkom bij Baeldung!")));

Deze tutorial maakt gebruik van de Apache HttpClient API om een ​​client weer te geven die verbinding maakt met de server:

CloseableHttpClient httpClient = HttpClients.createDefault ();

Een verzoek wordt uitgevoerd en een antwoord wordt achteraf geretourneerd:

HttpGet request = nieuwe HttpGet ("// localhost: 8080 / baeldung"); HttpResponse httpResponse = httpClient.execute (verzoek);

We zullen het httpResponse variabele naar een Draad met behulp van een hulpmethode:

String responseString = convertResponseToString (httpResponse);

Hier is de implementatie van die conversiehulpmethode:

private String convertResponseToString (HttpResponse response) gooit IOException {InputStream responseStream = response.getEntity (). getContent (); Scannerscanner = nieuwe scanner (responseStream, "UTF-8"); String responseString = scanner.useDelimiter ("\ Z"). Next (); scanner.close (); return responseString; }

De volgende code verifieert dat de server een verzoek heeft ontvangen naar de verwachte URL en dat het antwoord dat bij de client aankomt precies is wat er is verzonden:

verifieer (getRequestedFor (urlEqualTo ("/ baeldung"))); assertEquals ("Welkom bij Baeldung!", stringResponse);

Ten slotte moet de WireMock-server worden gestopt om systeembronnen vrij te maken:

wireMockServer.stop ();

4. Door JUnit beheerde server

In tegenstelling tot sectie 3, illustreert deze sectie het gebruik van een WireMock-server met behulp van JUnit Regel.

4.1. Server instellen

Een WireMock-server kan in JUnit-testcases worden geïntegreerd met behulp van de @Regel annotatie. Hierdoor kan JUnit de levenscyclus beheren, de server starten voorafgaand aan elke testmethode en stoppen nadat de methode is teruggekeerd.

Net als bij de programmatisch beheerde server, kan een door JUnit beheerde WireMock-server worden gemaakt als een Java-object met het opgegeven poortnummer:

@Rule publiek WireMockRule wireMockRule = nieuwe WireMockRule (int poort);

Als er geen argumenten worden opgegeven, zal de serverpoort de standaardwaarde aannemen, 8080. Serverhost, standaard ingesteld op localhost, en andere configuraties kunnen worden gespecificeerd met behulp van de Opties koppel.

4.2. URL-overeenkomst

Na het opzetten van een WireMockRule De volgende stap is bijvoorbeeld het configureren van een stub. In deze subsectie bieden we een REST-stub voor een service-eindpunt met behulp van reguliere expressie:

stubFor (get (urlPathMatching ("/ baeldung /.*")) .willReturn (aResponse () .withStatus (200) .withHeader ("Content-Type", "application / json") .withBody ("\" testbibliotheek \ ": \" WireMock \ "")));

Laten we verder gaan met het maken van een HTTP-client, het uitvoeren van een verzoek en een antwoord ontvangen:

CloseableHttpClient httpClient = HttpClients.createDefault (); HttpGet request = nieuwe HttpGet ("// localhost: 8080 / baeldung / wiremock"); HttpResponse httpResponse = httpClient.execute (verzoek); String stringResponse = convertHttpResponseToString (httpResponse);

Het bovenstaande codefragment maakt gebruik van een conversiehulpmethode:

private String convertHttpResponseToString (HttpResponse httpResponse) gooit IOException {InputStream inputStream = httpResponse.getEntity (). getContent (); return convertInputStreamToString (inputStream); }

Dit maakt op zijn beurt gebruik van een andere privémethode:

private String convertInputStreamToString (InputStream inputStream) {Scanner scanner = nieuwe scanner (inputStream, "UTF-8"); String string = scanner.useDelimiter ("\ Z"). Next (); scanner.close (); retourstring; }

De bewerkingen van de stub worden geverifieerd door de onderstaande testcode:

verifieer (getRequestedFor (urlEqualTo ("/ baeldung / wiremock"))); assertEquals (200, httpResponse.getStatusLine (). getStatusCode ()); assertEquals ("application / json", httpResponse.getFirstHeader ("Content-Type"). getValue ()); assertEquals ("\" testing-library \ ": \" WireMock \ "", stringResponse);

4.3. Verzoek Header Matching

Nu zullen we demonstreren hoe u een REST API stubt met het matchen van headers. Laten we beginnen met de stub-configuratie:

stubFor (get (urlPathEqualTo ("/ baeldung / wiremock")) .withHeader ("Accept", matching ("text /.*")) .willReturn (aResponse () .withStatus (503) .withHeader ("Content-Type" , "text / html") .withBody ("!!! Service niet beschikbaar !!!")));

Net als in de voorgaande subsectie, illustreren we HTTP-interactie met behulp van de HttpClient API, met behulp van dezelfde hulpmethoden:

CloseableHttpClient httpClient = HttpClients.createDefault (); HttpGet request = nieuwe HttpGet ("// localhost: 8080 / baeldung / wiremock"); request.addHeader ("Accepteer", "text / html"); HttpResponse httpResponse = httpClient.execute (verzoek); String stringResponse = convertHttpResponseToString (httpResponse);

De volgende verificatie en beweringen bevestigen functies van de stub die we eerder hebben gemaakt:

verifieer (getRequestedFor (urlEqualTo ("/ baeldung / wiremock"))); assertEquals (503, httpResponse.getStatusLine (). getStatusCode ()); assertEquals ("text / html", httpResponse.getFirstHeader ("Content-Type"). getValue ()); assertEquals ("!!! Service niet beschikbaar !!!", stringResponse);

4.4. Verzoek om body-matching

De WireMock-bibliotheek kan ook worden gebruikt om een ​​REST API te stubben met body-matching. Hier is de configuratie voor een stomp van deze soort:

stubFor (post (urlEqualTo ("/ baeldung / wiremock")) .withHeader ("Content-Type", equalTo ("application / json")) .withRequestBody (met ("\" testing-library \ ": \" WireMock \ "")) .withRequestBody (met ("\" creator \ ": \" Tom Akehurst \ "")) .withRequestBody (met ("\" website \ ": \" wiremock.org \ "")) .willReturn ( aResponse () .withStatus (200)));

Nu is het tijd om een StringEntity object dat zal worden gebruikt als de hoofdtekst van een verzoek:

InputStream jsonInputStream = this.getClass (). GetClassLoader (). GetResourceAsStream ("wiremock_intro.json"); String jsonString = convertInputStreamToString (jsonInputStream); StringEntity entiteit = nieuwe StringEntity (jsonString);

De bovenstaande code gebruikt een van de conversiehulpmethoden die eerder zijn gedefinieerd, convertInputStreamToString.

Hier is de inhoud van de wiremock_intro.json bestand op het klassenpad:

{"testing-library": "WireMock", "creator": "Tom Akehurst", "website": "wiremock.org"}

HTTP-verzoeken en -antwoorden kunnen als volgt worden geconfigureerd en uitgevoerd:

CloseableHttpClient httpClient = HttpClients.createDefault (); HttpPost request = nieuwe HttpPost ("// localhost: 8080 / baeldung / wiremock"); request.addHeader ("Content-Type", "application / json"); request.setEntity (entiteit); HttpResponse response = httpClient.execute (verzoek);

Dit is de testcode die wordt gebruikt om de stub te valideren:

verifieer (postRequestedFor (urlEqualTo ("/ baeldung / wiremock")) .withHeader ("Content-Type", equalTo ("application / json"))); assertEquals (200, response.getStatusLine (). getStatusCode ());

4.5. Stub-prioriteit

De voorgaande paragrafen behandelen situaties waarin een HTTP-verzoek slechts overeenkomt met een enkele stub. Het zou ingewikkelder zijn als er meer dan een match is voor een verzoek. Standaard heeft de meest recent toegevoegde stub voorrang in een dergelijk geval. Gebruikers mogen dat gedrag echter aanpassen om meer controle over WireMock-stubs te krijgen.

We zullen de werking van een WireMock-server demonstreren wanneer een komend verzoek overeenkomt met twee verschillende stubs, met en zonder het instellen van het prioriteitsniveau, tegelijkertijd. In beide scenario's wordt de volgende persoonlijke helper-methode gebruikt:

privé HttpResponse generationClientAndReceiveResponseForPriorityTests () gooit IOException {CloseableHttpClient httpClient = HttpClients.createDefault (); HttpGet request = nieuwe HttpGet ("// localhost: 8080 / baeldung / wiremock"); request.addHeader ("Accepteren", "text / xml"); retourneer httpClient.execute (verzoek); }

Configureer eerst twee stubs zonder rekening te houden met het prioriteitsniveau:

stubFor (get (urlPathMatching ("/ baeldung /.*")) .willReturn (aResponse () .withStatus (200))); stubFor (get (urlPathEqualTo ("/ baeldung / wiremock")) .withHeader ("Accept", matching ("text /.*")) .willReturn (aResponse () .withStatus (503)));

Maak vervolgens een HTTP-client en voer een verzoek uit met behulp van de hierboven beschreven helper-methode:

HttpResponse httpResponse = genererenClientAndReceiveResponseForPriorityTests ();

Het volgende codefragment verifieert dat de laatst geconfigureerde stub wordt toegepast, ongeacht de eerder gedefinieerde stub, wanneer een verzoek met beide overeenkomt:

verifieer (getRequestedFor (urlEqualTo ("/ baeldung / wiremock"))); assertEquals (503, httpResponse.getStatusLine (). getStatusCode ());

Laten we verder gaan met stubs waarbij prioriteitsniveaus zijn ingesteld, waarbij een lager getal een hogere prioriteit vertegenwoordigt:

stubFor (get (urlPathMatching ("/ baeldung /.*")) .atPriority (1) .willReturn (aResponse () .withStatus (200))); stubFor (get (urlPathEqualTo ("/ baeldung / wiremock")) .atPriority (2) .withHeader ("Accept", matching ("text /.*")) .willReturn (aResponse () .withStatus (503)));

Aanmaken en uitvoeren van een HTTP-verzoek:

HttpResponse httpResponse = genererenClientAndReceiveResponseForPriorityTests ();

De volgende code valideert het effect van prioriteitsniveaus, waarbij de eerste geconfigureerde stub wordt toegepast in plaats van de laatste:

verifieer (getRequestedFor (urlEqualTo ("/ baeldung / wiremock"))); assertEquals (200, httpResponse.getStatusLine (). getStatusCode ());

5. Conclusie

Deze tutorial introduceerde WireMock en hoe je deze bibliotheek instelt en configureert voor het testen van REST API's met behulp van verschillende technieken, waaronder het matchen van URL's, request headers en body.

De implementatie van alle voorbeelden en codefragmenten is te vinden in een GitHub-project.


$config[zx-auto] not found$config[zx-overlay] not found