WireMock-Tutorial:Anfrageabgleich, Teil drei
Dieser Blogbeitrag beschreibt, wie wir Erwartungen für das JSON-Dokument angeben können, das von unserem WireMock-Server empfangen wird. Nachdem wir diesen Blogbeitrag fertiggestellt haben, werden wir:
- Kann das tatsächliche JSON-Dokument mit dem erwarteten JSON-Dokument vergleichen.
- Verstehen Sie, wie wir sicherstellen können, dass ein Attribut aus dem JSON-Dokument gefunden wird.
- Wissen, wie wir den tatsächlichen Attributwert mit dem erwarteten Attributwert vergleichen können.
- Kann sicherstellen, dass die Größe eines Attributs dem erwarteten Wert entspricht.
- Verstehen, wie wir Erwartungen für Unterdokumente spezifizieren können.
Fangen wir an.
Erste Schritte
Wie wir uns erinnern, müssen wir, bevor wir unsere Erwartungen für das von unserem WireMock-Server empfangene JSON-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 eine 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 JSON-Dokument spezifizieren möchten, müssen wir die folgenden Schritte ausführen:
- Rufen Sie den
withRequestBody()
auf Methode desMappingBuilder
Schnittstelle. - Geben Sie unsere Erwartungen an, indem Sie einen neuen
ContentPattern
erstellen Objekt und übergeben Sie das erstellte Objekt anwithRequestBody()
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 JSON-Dokuments spezifizieren, können wir diese drei Methoden verwenden:
- Der
equalToJson()
-Methode stellt sicher, dass das tatsächliche JSON-Dokument mit dem als Methodenparameter angegebenen JSON-Dokument übereinstimmt. - Die
matchingJsonPath(String value)
-Methode stellt sicher, dass das tatsächliche JSON-Dokument mit dem als Methodenparameter angegebenen JsonPath-Ausdruck übereinstimmt. - Die
matchingJsonPath(String value, StringValuePattern valuePattern)
-Methode stellt sicher, dass der mithilfe eines JsonPath-Ausdrucks abgerufene Wert gleich dem erwarteten Wert ist, der mithilfe vonStringValuePattern
angegeben wird Objekt.
Als Nächstes sehen wir uns einige Beispiele an, die zeigen, wie wir diese Methoden verwenden können, wenn wir unsere Erwartungen an das von unserem WireMock-Server empfangene JSON-Dokument spezifizieren.
Vergleichen des tatsächlichen JSON-Dokuments mit dem erwarteten JSON-Dokument
Wenn wir sicherstellen wollen, dass das tatsächliche JSON-Dokument dem erwarteten JSON-Dokument entspricht, müssen wir unsere Erwartung mit dem equalToJson()
spezifizieren Methode des WireMock
Klasse. Standardmäßig ignoriert diese Methode die Array-Reihenfolge und zusätzliche Attribute nicht. Das bedeutet:
- Wenn das tatsächliche JSON-Dokument ein Attribut enthält, das im erwarteten JSON-Dokument nicht gefunden wird, wird unsere Erwartung nicht erfüllt.
- Wenn das tatsächliche JSON-Dokument ein Array enthält, das aus dem erwarteten JSON-Dokument gefunden wird, müssen beide Arrays die gleiche Reihenfolge verwenden oder unsere Erwartung wird nicht erfüllt.
Schauen wir uns drei Beispiele an, die zeigen, wie diese Methode funktioniert.
Beispiel 1:Angabe des erwarteten JSON-Dokuments
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "message": "Hello World!" }
Wenn wir erwarten, dass unser WireMock-Server dieses JSON-Dokument empfängt, müssen wir unsere Erwartung spezifizieren, indem wir das erwartete JSON-Dokument an equalToJson()
ü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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual json with the expected json") void shouldCompareActualRequestBodyWithExpectedRequestBody() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(equalToJson("{\"message\": \"Hello World!\"}")) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"message\": \"Hello World!\"}" ); 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() ); } }
Beispiel 2:Ignorieren zusätzlicher Attribute
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "name": "Petri Kainulainen", "message": "Hello World!" }
Wenn wir erwarten, dass unser WireMock-Server ein JSON-Dokument empfängt, das nicht den name
enthält -Attribut müssen wir die zusätzliche Attributprüfung deaktivieren, wenn wir equalToJson()
aufrufen Methode des WireMock
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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual json with the expected json") void shouldCompareActualRequestBodyWithExpectedRequestBody() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(equalToJson("{\"message\": \"Hello World!\"}", false, true )) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"name\": \"Petri Kainulainen\", \"message\": \"Hello World!\"}" ); 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() ); } }
Beispiel 3:Ignorieren der Array-Reihenfolge
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "messages": ["foobar", "Hello World!"] }
Wenn wir erwarten, dass unser WireMock-Server ein JSON-Dokument mit dem messages
erhält Array, das anders sortiert ist, müssen wir die Prüfung der Array-Reihenfolge deaktivieren, wenn wir equalToJson()
aufrufen Methode des WireMock
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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should compare the actual json with the expected json") void shouldCompareActualRequestBodyWithExpectedRequestBody() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(equalToJson( "{\"messages\": [\"Hello World!\", \"foobar\"]}", true, false )) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"messages\": [\"foobar\", \"Hello World!\"]}" ); 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 Attribut aus dem JSON-Dokument gefunden wird, das von unserem WireMock-Server empfangen wird.
Überprüfen, ob ein Attribut aus dem empfangenen JSON-Dokument gefunden wurde
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "message": "Hello World!" }
Wenn wir erwarten, dass das empfangene JSON-Dokument den message
hat Attribut müssen wir unsere Erwartung mit matchingJsonPath()
spezifizieren Methode des WireMock
Klasse. Wenn wir diese Methode aufrufen, müssen wir einen JsonPath-Ausdruck erstellen, der den Wert des erwarteten Attributs zurückgibt, und diesen Ausdruck an matchingJsonPath()
ü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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that the actual request body contains an attribute") void shouldEnsureThatActualRequestBodyContainsAttribute() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(matchingJsonPath("$.message")) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"message\": \"Hello World!\"}" ); 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 Attributwert mit dem erwarteten Attributwert vergleichen können.
Vergleich des tatsächlichen Attributwerts mit dem erwarteten Attributwert
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "message": "Hello World!" }
Wenn wir sicherstellen wollen, dass der Wert von message
Attribut ist:'Hello World!', müssen wir unsere Erwartung spezifizieren, indem wir den matchingJsonPath()
verwenden Methode des WireMock
Klasse. Wir können den erwarteten Wert angeben, indem wir eine dieser beiden Optionen verwenden:
Zuerst , können wir einen JsonPath-Ausdruck erstellen, der den erwarteten Wert angibt, und diesen Ausdruck an matchingJsonPath()
ü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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that the given attribute has the expected value") void shouldEnsureThatActualRequestBodyHasAttributeWithExpectedValue() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(matchingJsonPath( "$.[?(@.message == 'Hello World!')]") ) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"message\": \"Hello World!\"}" ); 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 JsonPath-Ausdruck mit einem Matcher kombinieren. Wenn wir diese Technik verwenden wollen, müssen wir dem matchingJsonPath()
zwei Methodenparameter zur Verfügung stellen Methode:
- Ein JsonPath-Ausdruck, der den tatsächlichen Wert des Attributs zurückgibt.
- 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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that the given attribute has the expected value") void shouldEnsureThatActualRequestBodyHasAttributeWithExpectedValue() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(matchingJsonPath("$.message", equalTo("Hello World!") )) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"message\": \"Hello World!\"}" ); 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 die Größe eines Attributs korrekt ist.
Sicherstellen, dass die Größe eines Attributs korrekt ist
Nehmen wir an, das zu testende System sendet das folgende JSON-Dokument an unseren WireMock-Server:
{ "messages": ["Hello World!"] }
Wenn wir erwarten, dass die messages
-Attribut nur eine Nachricht hat, müssen wir unsere Erwartung mit matchingJsonPath()
spezifizieren Methode des WireMock
Klasse. Wenn wir diese Methode aufrufen, müssen wir einen JsonPath-Ausdruck erstellen, der die erwartete Größe von messages
angibt -Attribut und übergeben Sie diesen Ausdruck an matchingJsonPath()
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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that the attribute has the expected size") void shouldEnsureThatActualRequestBodyHasAttributeWithExpectedValue() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(matchingJsonPath("$[?(@.messages.size() == 1)]")) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>( "{\"messages\": [\"Hello World!\"]}" ); 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 JSON-Dokument an unseren WireMock-Server:
{ "message": { "name": "Petri Kainulainen", "text": "Hello World" } }
Wenn wir sicherstellen wollen, dass der message
-Attribut das richtige Unterdokument enthält, können wir unsere Erwartung mit matchingJsonPath()
spezifizieren Methode des WireMock
Klasse. Wenn wir diese Methode aufrufen, müssen wir zwei Methodenparameter an die aufgerufene Methode übergeben:
- Ein JsonPath-Ausdruck, der den tatsächlichen Wert des Attributs zurückgibt.
- A
StringValuePattern
Objekt, das das erwartete Unterdokument angibt. Da wir das erwartete Unterdokument im JSON-Format angeben möchten, müssen wir den erforderlichenStringValuePattern
erstellen Objekt mit demequalToJson()
Methode desWireMock
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; class RequestMatchingTest { private RestTemplate restTemplate; private WireMockServer wireMockServer; @Test @DisplayName("Should ensure that the json has the expected sub-document") void shouldEnsureThatActualRequestBodyHasAttributeWithExpectedSubDocument() { givenThat(post(urlEqualTo("/api/message")) .withRequestBody(matchingJsonPath("$.message", equalToJson("{" + "\"name\": \"Petri\", " + "\"text\": \"Hello World!\"" + "}")) ) .willReturn(aResponse().withStatus(200)) ); String apiMethodUrl = buildApiMethodUrl(); HttpEntity<String> httpRequest = new HttpEntity<>("" + "{\"message\": " + "{\"name\": \"Petri\", \"text\": \"Hello World!\"}" + "}"); 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 JSON-Dokumente spezifizieren. Fassen wir zusammen, was wir aus diesem Blogbeitrag gelernt haben.
Zusammenfassung
Dieser Blogpost hat uns sechs Dinge beigebracht:
- Wenn wir unsere Erwartungen an den Körper der empfangenen HTTP-Anfrage spezifizieren wollen, müssen wir den
withRequestBody()
aufrufen Methode desMappingBuilder
Schnittstelle. - Wenn wir unsere Erwartungen an das empfangene JSON-Dokument spezifizieren wollen, müssen wir einen neuen
ContentPattern
erstellen Objekt und übergeben Sie dieses Objekt anwithRequestBody()
method als Methodenparameter. - Wir können den erforderlichen
ContentPattern
erstellen Objekt mit demstatic
Fabrikmethoden desWireMock
Klasse. - Der
equalToJson()
Methode desWireMock
-Klasse ermöglicht es uns, das tatsächliche JSON-Dokument mit dem erwarteten JSON-Dokument zu vergleichen. - Der
matchingJsonPath()
Methode desWireMock
-Klasse können wir unsere Erwartungen mithilfe von JsonPath-Ausdrücken spezifizieren. - Der
matchingJsonPath()
Methode desWireMock
-Klasse ermöglicht es uns, JsonPath-Ausdrücke mit Matchern zu kombinieren (StringValuePattern
Objekte).