Java >> Java Tutorial >  >> Java

WireMock-Tutorial:Anfrageabgleich, Teil 4

Dieser Blogbeitrag beschreibt, wie wir Erwartungen an das XML-Dokument spezifizieren können, das von unserem WireMock-Server empfangen wird. Nachdem wir diesen Blogbeitrag fertiggestellt haben, werden wir:

  • Kann das tatsächliche XML-Dokument mit dem erwarteten XML-Dokument vergleichen.
  • Verstehen, wie wir sicherstellen können, dass ein Element aus dem XML-Dokument gefunden wird.
  • Wissen, wie wir den tatsächlichen Elementwert mit dem erwarteten Elementwert vergleichen können.
  • Kann sicherstellen, dass das empfangene Dokument X Elemente enthält.
  • Verstehen, wie wir Erwartungen für Unterdokumente spezifizieren können.
  • Wissen, wie wir mit XML-Namespaces umgehen können.

Fangen wir an.

Erste Schritte

Wie wir uns erinnern, müssen wir, bevor wir unsere Erwartungen an das von unserem WireMock-Server empfangene XML-Dokument angeben 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 einen POST empfängt Anfrage an die URL:'/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(post(urlEqualTo("/api/message"))
 //Specify the other expectations here
 .willReturn(aResponse().withStatus(200))
 );

 String serverUrl = buildApiMethodUrl();
 ResponseEntity<String> response = restTemplate.getForEntity(serverUrl,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }


 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Wenn wir unsere Erwartungen an das empfangene XML-Dokument spezifizieren wollen, müssen wir diesen Schritten folgen:

  1. Rufen Sie den withRequestBody() auf Methode des MappingBuilder Schnittstelle.
  2. Geben Sie unsere Erwartungen an, indem Sie einen neuen ContentPattern erstellen Objekt und übergeben Sie das erstellte Objekt an withRequestBody() method als Methodenparameter.

Wir können den erforderlichen ContentPattern erstellen Objekt mit dem static Factory-Methoden der WireMock Klasse. Wenn wir unsere Erwartungen an den Inhalt des empfangenen XML-Dokuments spezifizieren, können wir diese drei Methoden verwenden:

  • Der equalToXml(String value) Methode stellt sicher, dass das eigentliche XML-Dokument gleich dem als Methodenparameter angegebenen XML-Dokument ist.
  • Die matchingXPath(String value) -Methode stellt sicher, dass das tatsächliche XML-Dokument mit dem als Methodenparameter angegebenen XPath-Ausdruck übereinstimmt.
  • Die matchingXPath(String value, StringValuePattern valuePattern) -Methode stellt sicher, dass der mithilfe eines XPath-Ausdrucks abgerufene Wert gleich dem erwarteten Wert ist, der mithilfe von StringValuePattern angegeben wird Objekt.

Als Nächstes werfen wir einen Blick auf einige Beispiele, die zeigen, wie wir diese Methoden verwenden können, wenn wir unsere Erwartungen an das von unserem WireMock-Server empfangene XML-Dokument spezifizieren.

Vergleichen des tatsächlichen XML-Dokuments mit dem erwarteten XML-Dokument

Wenn wir sicherstellen wollen, dass das tatsächliche XML-Dokument gleich dem erwarteten XML-Dokument ist, müssen wir unsere Erwartung mit dem equalToXml() spezifizieren Methode des WireMock Klasse. Wenn wir diese Methode verwenden, müssen wir diese drei Dinge wissen:

  • Diese Methode nimmt das erwartete XML-Dokument als Methodenparameter.
  • Standardmäßig ignoriert diese Methode die Reihenfolge von XML-Attributen, aber nicht die Reihenfolge von XML-Elementen. Mit anderen Worten, wenn wir diese Methode verwenden, müssen die Elemente des erwarteten XML-Dokuments sein in derselben Reihenfolge wie die Elemente des eigentlichen XML-Dokuments.
  • Da WireMock XMLUnit verwendet, können wir die XML-Vergleichseinstellungen mithilfe von static konfigurieren setXXX() Methoden des XMLUnit Klasse.

Als nächstes sehen wir uns ein Beispiel an, das zeigt, wie diese Methode funktioniert. Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<message>Hello World!</message>

Wenn wir erwarten, dass unser WireMock-Server dieses XML-Dokument empfängt, müssen wir unsere Erwartung spezifizieren, indem wir das erwartete XML-Dokument an equalToXml() übergeben method als Methodenparameter.

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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should compare the actual xml with the expected xml")
 void shouldCompareActualRequestBodyWithExpectedRequestBody() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(equalToXml("<message>Hello World!</message>"))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>(
 "<message>Hello World!</message>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message", 
 this.wireMockServer.port()
 );
 }
}

Lassen Sie uns weitermachen und herausfinden, wie wir sicherstellen können, dass ein Element aus dem von unserem WireMock-Server empfangenen XML-Dokument gefunden wird.

Überprüfen, ob ein Element im empfangenen XML-Dokument gefunden wurde

Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<message>Hello World!</message>

Wenn wir erwarten, dass das empfangene XML-Dokument den message hat -Element müssen wir unsere Erwartung mit matchingXPath() spezifizieren Methode des WireMock Klasse. Wenn wir diese Methode aufrufen, müssen wir einen XPath-Ausdruck erstellen, der das erwartete Element identifiziert, und diesen Ausdruck an matchingXPath() übergeben method als Methodenparameter.

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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should ensure that the actual request body contains an element")
 void shouldEnsureThatActualRequestBodyContainsElement() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath("/message"))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>(
 "<message>Hello World!</message>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Als nächstes werden wir herausfinden, wie wir den tatsächlichen Elementwert mit dem erwarteten Elementwert vergleichen können.

Vergleich des tatsächlichen Elementwerts mit dem erwarteten Elementwert

Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<message>Hello World!</message>

Wenn wir sicherstellen wollen, dass der Wert von message Element ist:'Hello World!', müssen wir unsere Erwartung mit matchingXPath() spezifizieren Methode des WireMock Klasse. Wir können den erwarteten Wert angeben, indem wir eine dieser beiden Optionen verwenden:

Zuerst , können wir einen XPath-Ausdruck erstellen, der den erwarteten Wert angibt, und diesen Ausdruck an matchingXPath() übergeben method als Methodenparameter. 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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should ensure that the given element has the expected value")
 void shouldEnsureThatActualRequestBodyHasElementWithExpectedValue() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath("/message[text()='Hello World!']"))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>(
 "<message>Hello World!</message>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Zweiter , können wir einen XPath-Ausdruck mit einem Matcher kombinieren. Wenn wir diese Technik verwenden wollen, müssen wir dem matchingXPath() zwei Methodenparameter zur Verfügung stellen Methode:

  1. Ein XPath-Ausdruck, der den tatsächlichen Wert des Elements zurückgibt.
  2. A StringValuePattern Objekt, das den erwarteten Wert angibt.

Nachdem wir unsere Erwartung mit dieser Technik 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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should ensure that the given element has the expected value")
 void shouldEnsureThatActualRequestBodyHasElementWithExpectedValue() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath("/message/text()", 
 equalTo("Hello World!")
 ))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>(
 "<message>Hello World!</message>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Lassen Sie uns weitermachen und herausfinden, wie wir sicherstellen können, dass das XML-Dokument X-Elemente enthält.

Sicherstellen, dass das XML-Dokument X Elemente enthält

Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<messages>
 <message>Hello World!</message>
</messages>

Wenn wir erwarten, dass das empfangene XML-Dokument nur einen message hat -Element müssen wir unsere Erwartung mit matchingXPath() spezifizieren Methode des WireMock Klasse. Wenn wir diese Methode aufrufen, müssen wir einen XPath-Ausdruck erstellen, der die erwartete Zahl von message angibt Elemente und übergeben Sie diesen Ausdruck an matchingXPath() method als Methodenparameter.

Nachdem wir unsere Erwartung mit dieser Technik 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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should ensure that the document has X elements")
 void shouldEnsureThatActualRequestBodyHasXElements() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath("/messages[count(message)=1]"))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>("<messages>" +
 "<message>Hello World!</message>" +
 "</messages>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Als nächstes werden wir herausfinden, wie wir Erwartungen für Unterdokumente spezifizieren können.

Angabe von Erwartungen für Unterdokumente

Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<message>
 <name>Petri</name>
 <text>Hello World!</text>
</message>

Wenn wir sicherstellen wollen, dass der name Element das richtige Teildokument enthält, können wir unsere Erwartung mit matchingXPath() spezifizieren Methode des WireMock Klasse. Wenn wir diese Methode aufrufen, müssen wir zwei Methodenparameter an die aufgerufene Methode übergeben:

  1. Ein XPath-Ausdruck, der den tatsächlichen Wert des Elements zurückgibt.
  2. A StringValuePattern Objekt, das das erwartete Unterdokument angibt. Da wir das erwartete Unterdokument im XML-Format angeben möchten, müssen wir den erforderlichen StringValuePattern erstellen Objekt mit dem equalToXml() Methode des WireMock Klasse. Wenn wir diese Methode aufrufen, müssen wir das erwartete Unterdokument als Methodenparameter an die aufgerufene Methode übergeben.

Nachdem wir unsere Erwartung mit dieser Technik 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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should ensure that the XML has the expected sub-document")
 void shouldEnsureThatActualRequestBodyHasElementWithExpectedSubDocument() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath("/message/name",
 equalToXml("<name>Petri</name>")
 ))
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>("<message>" +
 "<name>Petri</name>" +
 "<text>Hello World!</text>" +
 "</message>"
 );

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Lassen Sie uns weitermachen und herausfinden, wie wir mit XML-Namespaces umgehen können.

Umgang mit XML-Namespaces

Nehmen wir an, das zu testende System sendet das folgende XML-Dokument an unseren WireMock-Server:

<sample:message xmlns:sample="http://www.example.com">Hello World!</sample:message>

Wenn wir Erwartungen an ein XML-Dokument spezifizieren wollen, das Namespaces verwendet, müssen wir die verwendeten Namespaces mit dem withXPathNamespace() deklarieren Methode des MatchesXPathPattern Klasse. Diese Methode benötigt zwei Methodenparameter:

  1. Der Name des XML-Namensraums.
  2. Der URI des XML-Namensraums.

Wenn wir zum Beispiel sicherstellen wollen, dass der sample:message -Element den Text „Hello World!“ enthält, müssen wir unsere Erwartung wie folgt spezifizieren:

  1. Erstellen Sie einen XPath-Ausdruck, der den erwarteten Wert von sample:message angibt Element.
  2. Deklarieren Sie den sample Namespace durch Aufrufen von withXPathNamespace() Methode des MatchesXPathPattern Klasse.

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.HttpEntity;
import org.springframework.http.HttpMethod;
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;

@DisplayName("Specify expectations for an XML document")
class RequestMatchingTest {

 private RestTemplate restTemplate;
 private WireMockServer wireMockServer;

 @Test
 @DisplayName("Should compare the actual XML with the expected XML")
 void shouldCompareActualRequestBodyWithExpectedRequestBody() {
 givenThat(post(urlEqualTo("/api/message"))
 .withRequestBody(matchingXPath(
 "/sample:message[text()='Hello World!']"
 )
 .withXPathNamespace("sample", "http://www.example.com")
 )
 .willReturn(aResponse().withStatus(200))
 );

 String apiMethodUrl = buildApiMethodUrl();
 HttpEntity<String> httpRequest = new HttpEntity<>(
 "<sample:message xmlns:sample=\"http://www.example.com\">" +
 "Hello World!" +
 "</sample:message>");

 ResponseEntity<String> response = restTemplate.exchange(apiMethodUrl,
 HttpMethod.POST,
 httpRequest,
 String.class
 );
 assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
 }

 private String buildApiMethodUrl() {
 return String.format("http://localhost:%d/api/message",
 this.wireMockServer.port()
 );
 }
}

Wir können jetzt Erwartungen für die von unserem WireMock-Server empfangenen XML-Dokumente spezifizieren. Fassen wir zusammen, was wir aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogbeitrag hat uns sieben Dinge beigebracht:

  • Wenn wir unsere Erwartungen an den Körper der empfangenen HTTP-Anfrage spezifizieren wollen, müssen wir den withRequestBody() aufrufen Methode des MappingBuilder Schnittstelle.
  • Wenn wir unsere Erwartungen an das empfangene XML-Dokument spezifizieren wollen, müssen wir einen neuen ContentPattern erstellen Objekt und übergeben Sie dieses Objekt an withRequestBody() method als Methodenparameter.
  • Wir können den erforderlichen ContentPattern erstellen Objekt, indem Sie die statischen Factory-Methoden des WireMock verwenden Klasse.
  • Der equalToXml() Methode des WireMock -Klasse ermöglicht es uns, das tatsächliche XML-Dokument mit dem erwarteten XML-Dokument zu vergleichen.
  • Der matchingXPath() Methode des WireMock -Klasse ermöglicht es uns, unsere Erwartungen durch die Verwendung von XPath-Ausdrücken zu spezifizieren.
  • Der matchingXPath() Methode des WireMock Klasse ermöglicht es uns, XPath-Ausdrücke mit Matchern zu kombinieren (StringValuePattern Objekte).
  • Wenn wir Erwartungen an ein XML-Dokument spezifizieren wollen, das Namensräume verwendet, müssen wir die verwendeten Namensräume mit dem withXPathNamespace() deklarieren Methode des MatchesXPathPattern Klasse.

Java-Tag