Frage

Ich bin die Implementierung eines Client eine Webservice verbrauchen. Ich will Abhängigkeiten verringern und beschlossen, den Webservice zu verspotten.
Ich benutze Mockito , hat es den Vorteil gegenüber EasyMock zu können Klassen verspotten, nicht nur eine Schnittstelle. Aber das ist nicht der Punkt.

In meinem Test habe ich diesen Code habe:

// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);

// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
    Float.toString(A_LOCATION_BEAN.getLon()));

// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
    .getInstance();
LocationBean locationBean = geoLocationFetcher
    .extractGeoLocationFromXml(mDocument);

// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();

assertEquals(A_LOCATION_BEAN, locationBean);

Was mein Code zeigt, ist, dass ich „Mikro-Test“ das verzehrende Objekt. Es ist wie würde ich meinen produktiven Code in meinem Test implementieren. Ein Beispiel für das Ergebnis xml ist London auf GeoNames . Meiner Meinung nach ist es viel zu körnig.

Aber wie kann ich verspotten eine Webservice ohne everystep zu geben? Soll ich das Mock-Objekt nur zurückgeben eine XML-Datei lassen?

Es geht nicht um den Code, aber der Ansatz .

Ich bin mit JUnit 4.x und Mockito 1.7

War es hilfreich?

Lösung

Sie wollen, um wirklich die Ergebnisse aus dem Webservice an den Code zurückgegeben spöttisch, die das Ergebnis verwenden werden. In Ihrem Codebeispiel oben scheinen Sie mDocument zu verspotten, aber Sie wollen wirklich in einer Instanz von mDocument zu übergeben, die von einer verspottet Instanz Ihrer Webservice zurückgegeben wurde und behaupten, dass die locationBean kehrte von der geoLocationFetcher den Wert von A_LOCATION_BEAN entspricht.

Andere Tipps

Ich denke, das eigentliche Problem hier ist, dass man eine Singleton hat, die die Web-Service-Anrufe und schaffen so ist es schwierig, ein Modell eines einzufügen.

Sie müssen (möglicherweise Paketebene) Zugriff auf die Singleton-Klasse hinzufügen. Zum Beispiel, wenn der Konstruktor so etwas wie

sieht
private GeoLocationFactory(WebService service) {
   ...
}

Sie können die Konstruktor Paketebene machen und erstellen Sie einfach eine mit einem verspottet Web-Service.

Alternativ können Sie den Webservice festgelegt durch eine Setter-Methode hinzugefügt, obwohl ich nicht wandelbar Singletons mag. Auch in diesem Fall müssen Sie daran denken, die WebService unscharf zu schalten danach.

Wenn der Webservice in einem Verfahren erzeugt wird, müssen Sie möglicherweise die GeoLocationFactory erweiterbar machen den mock-Service zu ersetzen.

Sie können auch in Entfernen schauen die Singleton selbst. Es gibt Artikel online und wahrscheinlich hier, wie das zu tun.

Die einfachste Möglichkeit wäre, den WebService-Client zu verspotten,

when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
    .thenReturn("<location/>");

Sie können den Code modifizieren, um die Antwort xml aus dem Dateisystem zu lesen.

Beispielcode finden Sie hier: Mocking .NET WebServices mit Mockito

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top