WireMock-Tutorial:Anfrageabgleich, Teil 2
Dieser Blogbeitrag beschreibt, wie wir die Anfrageabgleichsunterstützung von WireMock verwenden können, wenn wir Erwartungen für Cookies, HTTP-Header und Anfrageparameter angeben möchten. Nachdem wir diesen Blogbeitrag fertiggestellt haben, werden wir:
- Kann den tatsächlichen Cookie-Wert mit dem erwarteten Cookie-Wert vergleichen.
- Wissen, wie wir den tatsächlichen Header-Wert mit dem erwarteten Header-Wert vergleichen können.
- Verstehen, wie wir den tatsächlichen Anforderungsparameterwert mit dem erwarteten Anforderungsparameterwert vergleichen können.
Fangen wir an.
Erste Schritte
Wie wir uns erinnern, müssen wir, bevor wir unsere Erwartungen für die anderen Attribute einer HTTP-Anforderung spezifizieren können, die erwartete Anforderungsmethode und die Anforderungs-URL angeben. Nachdem wir dies getan haben, können wir unsere anderen Erwartungen spezifizieren, indem wir einen MappingBuilder
verwenden Objekt.
Wenn wir zum Beispiel erwarten, dass unser WireMock-Server eine GET
empfängt Anfrage an den URL-Pfad:'/api/message', können wir den erforderlichen MappingBuilder
erstellen Objekt, indem Sie den folgenden Code verwenden:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static org.assertj.core.api.Assertions.assertThat; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual URL path with the expected URL path") void shouldCompareActualUrlWithExpectedUrlRegex() { givenThat(get(urlPathEqualTo("/api/message")) //Specify the other expectations here .willReturn(aResponse().withStatus(200)) ); String serverUrl = buildApiMethodUrl(1L); ResponseEntity<String> response = restTemplate.getForEntity(serverUrl, String.class ); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } private String buildApiMethodUrl(Long messageId) { return String.format("http://localhost:%d/api/message?id=%d", this.wireMockServer.port(), messageId ); } }
Wenn wir unsere Erwartungen an Cookies, HTTP-Header und Anforderungsparameter spezifizieren möchten, müssen wir diese von MappingBuilder
bereitgestellten Methoden verwenden Schnittstelle:
- Der
withCookie()
-Methode ermöglicht es uns, den tatsächlichen Cookie-Wert mit dem erwarteten Cookie-Wert zu vergleichen. - Der
withHeader()
-Methode ermöglicht es uns, den tatsächlichen Header-Wert mit dem erwarteten Header-Wert zu vergleichen. - Der
withQueryParam()
-Methode ermöglicht es, den tatsächlichen Anforderungsparameterwert mit dem erwarteten Anforderungsparameterwert zu vergleichen.
Diese Methoden nehmen zwei Methodenparameter entgegen:
- Der Name des Cookies, Headers oder Anforderungsparameters.
- A
StringValuePattern
Objekt, das den erwarteten Wert angibt.
Wir können den erforderlichen StringValuePattern
erstellen Objekt mit dem static
Fabrikmethoden des WireMock
Klasse. Wenn wir den erwarteten Wert eines Cookies, eines Headers oder eines Anforderungsparameters angeben, können wir diese fünf Methoden verwenden:
- Die
equalTo()
Methode stellt sicher, dass der tatsächliche Wert gleich dem als Methodenparameter angegebenen String ist. - Die
equalToIgnoreCase()
Die Methode ignoriert die Groß-/Kleinschreibung und stellt sicher, dass der tatsächliche Wert gleich der als Methodenparameter angegebenen Zeichenfolge ist. - Der
containing()
Methode stellt sicher, dass der eigentliche Wert die als Methodenparameter angegebene Zeichenfolge enthält. - Die
matching()
Methode stellt sicher, dass der tatsächliche Wert mit der als Methodenparameter angegebenen Regex übereinstimmt. - Der
notMatching()
Methode stellt sicher, dass der tatsächliche Wert nicht mit der als Methodenparameter angegebenen Regex übereinstimmt.
Als nächstes werden wir herausfinden, wie wir Erwartungen an Cookies spezifizieren können.
Angaben zu Cookies
Wenn wir erwarten, dass der Wert von name
cookie ist gleich:'Petri Kainulainen', wir müssen unsere Erwartung angeben, indem wir den withCookie()
verwenden Methode des MappingBuilder
Schnittstelle.
Nachdem wir unsere Erwartung spezifiziert haben, sieht der Quellcode unserer Testklasse wie folgt aus:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static org.assertj.core.api.Assertions.assertThat; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual value with the expected value") void shouldCompareActualUrlWithExactExpectedUrl() { givenThat(get(urlEqualTo("/api/message?id=1")) .withCookie("name", equalTo("Petri Kainulainen")) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(1L); HttpEntity<String> httpRequest = createHttpRequest(); ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl, HttpMethod.GET, httpRequest, String.class ); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } private HttpEntity<String> createHttpRequest() { HttpHeaders headers = new HttpHeaders(); headers.set("Cookie", "name=Petri Kainulainen"); return new HttpEntity<>(headers); } private String buildApiMethodUrl(Long messageId) { return String.format("http://localhost:%d/api/message?id=%d", this.wireMockServer.port(), messageId ); } }
Lassen Sie uns weitermachen und herausfinden, wie wir Erwartungen für HTTP-Header spezifizieren können.
Erwartungen für HTTP-Header angeben
Wenn wir erwarten, dass der Wert von Accept
Header gleich ist:'application/json;charset=UTF-8', müssen wir unsere Erwartung mit withHeader()
angeben Methode des MappingBuilder
Schnittstelle.
Nachdem wir unsere Erwartung spezifiziert haben, sieht der Quellcode unserer Testklasse wie folgt aus:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import java.util.Collections; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static org.assertj.core.api.Assertions.assertThat; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual value with the exact expected value") void shouldCompareActualUrlWithExactExpectedUrl() { givenThat(get(urlEqualTo("/api/message?id=1")) .withHeader("Accept", equalTo(MediaType.APPLICATION_JSON_UTF8_VALUE)) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(1L); HttpEntity<String> httpRequest = createHttpRequest(); ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl, HttpMethod.GET, httpRequest, String.class ); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } private HttpEntity<String> createHttpRequest() { HttpHeaders headers = new HttpHeaders(); headers.setAccept( Collections.singletonList(MediaType.APPLICATION_JSON_UTF8) ); return new HttpEntity<>(headers); } private String buildApiMethodUrl(Long messageId) { return String.format("http://localhost:%d/api/message?id=%d", this.wireMockServer.port(), messageId ); } }
Wenn wir die Standardauthentifizierung verwenden und sicherstellen möchten, dass unser WireMock-Server eine HTTP-Anforderung mit dem richtigen Benutzernamen und Passwort erhält, müssen wir den erwarteten Wert von Authorization
angeben Header.
Da es jedoch ziemlich umständlich ist, einen korrekt codierten Header-Wert zu konstruieren, wird der MappingBuilder
interface deklariert eine Methode, die uns die schwere Arbeit abnimmt. Diese Methode heißt withBasicAuth()
und es nimmt den erwarteten Benutzernamen und das Passwort als Methodenparameter.
Nachdem wir sichergestellt haben, dass der Authentication
Header den Benutzernamen:'username' und das Passwort:'password' enthält, sieht der Quellcode unserer Testklasse wie folgt aus:
import com.github.tomakehurst.wiremock.WireMockServer; import org.apache.commons.codec.binary.Base64; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import java.nio.charset.Charset; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static org.assertj.core.api.Assertions.assertThat; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that request has correct username and password") void shouldEnsureThatRequestHasCorrectUsernameAndPassword() { givenThat(get(urlEqualTo("/api/message?id=1")) .withBasicAuth("username", "password") .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(1L); HttpEntity<String> httpRequest = createHttpRequest(); ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl, HttpMethod.GET, httpRequest, String.class ); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } private HttpEntity<String> createHttpRequest() { HttpHeaders headers = new HttpHeaders(); String auth = "username:password"; byte[] encodedAuth = Base64.encodeBase64( auth.getBytes(Charset.forName("US-ASCII")) ); String authHeader = "Basic " + new String(encodedAuth); headers.set("Authorization", authHeader); return new HttpEntity<>(headers); } private String buildApiMethodUrl(Long messageId) { return String.format("http://localhost:%d/api/message?id=%d", this.wireMockServer.port(), messageId ); } }
Als nächstes werden wir herausfinden, wie wir Erwartungen für Anfrageparameter spezifizieren können.
Erwartungen für Anforderungsparameter angeben
Wenn wir erwarten, dass der Wert von searchTerm
Anfrageparameter ist gleich:'foobar', wir müssen unsere Erwartung angeben, indem wir den withQueryParam()
verwenden Methode des MappingBuilder
Schnittstelle.
Nachdem wir unsere Erwartung spezifiziert haben, sieht der Quellcode unserer Testklasse wie folgt aus:
import com.github.tomakehurst.wiremock.WireMockServer; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.*; import org.springframework.web.client.RestTemplate; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static org.assertj.core.api.Assertions.assertThat; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual value with the expected value") void shouldCompareActualUrlWithExactExpectedUrl() { givenThat(get(urlPathEqualTo("/api/message")) .withQueryParam("searchTerm", equalTo("foobar")) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl("foobar"); ResponseEntity<String> response = restTemplate.getForEntity(apiMethodUrl, String.class ); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); } private String buildApiMethodUrl(String searchTerm) { return String.format("http://localhost:%d/api/message?searchTerm=%s", this.wireMockServer.port(), searchTerm ); } }
Wir können jetzt unsere Erwartungen für Cookies, Header und Anfrageparameter spezifizieren. Fassen wir zusammen, was wir aus diesem Blogbeitrag gelernt haben.
Zusammenfassung
Diese Lektion hat uns fünf Dinge gelehrt:
- Bevor wir unsere Erwartungen für die anderen Attribute einer HTTP-Anforderung spezifizieren können, müssen wir die erwartete Anforderungsmethode und die Anforderungs-URL angeben.
- Wenn wir unsere Erwartungen an Cookies, HTTP-Header und Anforderungsparameter spezifizieren möchten, können wir die von
MappingBuilder
deklarierten Methoden verwenden Schnittstelle. - Wir können unsere Erwartungen durch die Verwendung einer fließenden API spezifizieren.
- Wir können einen neuen
StringValuePattern
erstellen Objekt, das den erwarteten Wert angibt, indem Sie denstatic
verwenden Fabrikmethoden desWireMock
Klasse. - Wenn wir Erwartungen für Anforderungsparameter spezifizieren, indem wir den
withQueryParam()
verwenden Methode, sollten wir die erwartete URL konfigurieren, indem wir einen pfadbasierten Abgleich verwenden.