Ich habe ungefähr 20 Methoden in Java geschrieben und alle rufen einige Webdienste auf. Keiner dieser Webdienste ist noch verfügbar. Um mit der serverseitigen Codierung fortzufahren, habe ich die Ergebnisse, die der Webdienst voraussichtlich liefern wird, fest codiert.
Können wir diese Methoden testen? Soweit ich weiß, verspotten Unit-Tests die Eingabewerte und sehen, wie das Programm reagiert. Ist es sinnvoll, sowohl Eingabe- als auch Ausgabewerte zu verspotten?
Bearbeiten:
Die Antworten hier legen nahe, dass ich Unit-Testfälle schreiben sollte.
Wie kann ich es jetzt schreiben, ohne den vorhandenen Code zu ändern?
Betrachten Sie den folgenden Beispielcode (hypothetischer Code):
public int getAge()
{
Service s = locate("ageservice"); // line 1
int age = s.execute(empId); // line 2
return age; // line 3
}
Wie verspotten wir die Ausgabe?
Im Moment kommentiere ich 'Zeile 1' aus und ersetze Zeile 2 durch int age= 50
. Ist das richtig ? Kann mich jemand auf den richtigen Weg hinweisen?
quelle
Ja, Sie sollten sich über Ihren Service lustig machen. Beim Verspotten werden Mock-Objekte verwendet , um die realen Objekte zu ersetzen, die Sie normalerweise zur Laufzeit verwenden würden. In den meisten Fällen möchten Sie ein Mocking-Framework verwenden, um Mock-Objekte einfach und dynamisch zu erstellen.
Wenn Sie Scheinobjekte verwenden, würden Sie wahrscheinlich Code schreiben, der eher so aussieht:
Wo
service
ist der eigentliche Dienst, den Sie zur Laufzeit verwenden werden, aber während eines Komponententests handelt es sich um ein Scheinobjekt mit Scheinverhalten. Beachten Sie, dass der Parameter fürgetAge
keine konkrete Klasse mehr ist, sondern eine Schnittstelle. Auf diese Weise können Sie jedes Objekt als Parameter verwenden, solange es die Schnittstelle implementiert, anstatt nur eine bestimmte Klasse. Ihr Komponententest würde dann die folgenden Schritte ausführen:execute
angerufen wirdgetAge
mit dem Scheinobjekt als Parameter aufgetAge
gibt das richtige Alter zurück.Eine gute Liste der Java-Mocking-Frameworks finden Sie in dieser Frage zum Stapelüberlauf .
BEARBEITEN
Kommentieren Sie Ihren Code nicht aus und ersetzen Sie ihn nur für Ihre Komponententests durch eine Konstante. Das Problem dabei ist, dass Sie sicherstellen müssen, dass beim Ausführen von Komponententests das Richtige und beim Freigeben an den Kunden das Richtige kommentiert wird. Dies würde zu einem Albtraum für langfristige Wartungszwecke werden, insbesondere wenn Sie beabsichtigen, mehr als zwei Komponententests zu schreiben, für die Verspottungen erforderlich sind. Abgesehen davon sollten Ihre Tests gegen das fertige Produkt durchgeführt werden . Wenn nicht, bedeutet dies, dass Sie nicht den tatsächlich freigegebenen Code testen, was den Zweck von Tests in erster Linie zunichte macht.
quelle
Ja, so ist es. Ihre Aufgabe ist es zu demonstrieren, dass Ihr Code in seiner Umgebung das Richtige tut. Die externen Webdienste sind Teil der Umgebung. Es ist nicht Ihre Aufgabe, ihre ordnungsgemäße Funktion zu testen, sondern die Aufgabe der Personen, die die Dienste schreiben. Die Eingabe / Ausgabe-Zuordnung, die die Tests überprüfen sollten, ist die Eingabe / Ausgabe für Ihren Code. Wenn der Code Eingaben für einen anderen Mitarbeiter erzeugt, um seine Arbeit zu erledigen, ist dies rein zufällig.
Selbst wenn die Webdienste verfügbar sind, ist es wahrscheinlich eine gute Idee, Ihre Komponententests in einer Scheinumgebung anstatt in der realen durchzuführen. Dies macht die Tests einfacher, weniger fragil in Bezug auf den erwarteten Systemkontext und wahrscheinlich auch schneller.
quelle
Um die hervorragende Antwort von emddudley zu ergänzen, besteht der größte Vorteil, den Sie durch das Verspotten des Dienstes erzielen können, darin, zu testen, was passieren sollte, wenn der Dienst nicht richtig funktioniert. Der Testpseudocode könnte ungefähr so aussehen:
Und jetzt wurde Ihre Implementierung mit dieser neuen Anforderung bearbeitet
In anderen Szenarien ist es wahrscheinlicher, dass Sie auf kompliziertere Antworten reagieren müssen. Wenn der Dienst die Kreditkartenverarbeitung bereitstellt, müssen Sie auf Erfolg, Nicht verfügbarer Dienst, Abgelaufene Kreditkarte, ungültige Nummer usw. reagieren. Durch Verspotten des Dienstes können Sie sicherstellen, dass Sie auf diese Szenarien entsprechend Ihrer Situation reagieren. In diesem Fall müssen Sie die Eingabe / Ausgabe des Dienstes verspotten, und das Feedback, das Sie erhalten, wenn Sie wissen, dass der konsumierende Code für alle bekannten Ausgaben funktioniert, ist in der Tat sinnvoll und wertvoll.
EDIT: Mir ist gerade aufgefallen, dass Sie verspotten möchten, ohne die vorhandene Methode zu ändern. Zu diesem
locate("ageservice");
Zweck müsste die Methode geändert werden, um Scheinobjekte in Tests zu unterstützen und den tatsächlichen Dienst zu lokalisieren, sobald er bereit ist. Dies ist eine Variation des Service Locator-Musters, das die Logik zum Abrufen der Implementierung des von Ihnen verwendeten Dienstes abstrahiert. Eine schnelle Version davon könnte folgendermaßen aussehen:Meine Empfehlung wäre jedoch, die Dienstabhängigkeiten in die Konstruktoren zu verschieben:
Jetzt ist die getAge-Methode nicht mehr dafür verantwortlich, den Dienst nachzuschlagen, da er vollständig aus der Klasse abstrahiert wurde und eine Implementierung wie diese übrig bleibt:
quelle
Nein, aber Sie verspotten den Eingabewert nicht. Ihr Test wird ausgeführt, und der Mock-Service überprüft, ob auf den richtigen Teil des Vertrags zugegriffen wird. Dass Sie zufällig einen bestimmten Wert zurückgeben, spielt keine Rolle.
Auf der anderen Seite ist der Rückgabewert wichtig, wenn Ihre Methode überhaupt eine Logik ausführt. Hier verspotten Sie die Eingaben in die Logik (das Ergebnis des Webdienstes) und testen die Ausgabe.
quelle
du kannst nicht. Sie können jedoch eine Schnittstelle "IMyService" erstellen, gegen die Sie programmieren können und die alle Webservice-Methodensignaturen enthält.
Im Produktionsmodus
getService();
wird ein Verweis auf einen voll funktionsfähigen Webservice und im Testmodus eine alternative Implementierung (oder ein Mock) zurückgegeben, die Ihre gefälschten Daten zurückgibt.quelle
Beim Verspotten geht es nicht um Ein- oder Ausgänge, sondern darum, externe Abhängigkeiten zu ersetzen. Also ja, es ist angebracht, Unit-Tests zu schreiben und die externen Webdienste zu verspotten.
Nun zu den schlechten Nachrichten: Abhängig von der Sprache und den Tools, die Ihnen zur Verfügung stehen, können Sie die externen Abhängigkeiten möglicherweise nicht verspotten, es sei denn, der Code wurde so konzipiert, dass Sie dies zulassen. Wenn dies der Fall ist, werden Ihre Tests tatsächlich eher zu kleinen Integrationstests als zu reinen Unti-Tests.
Auf der positiven Seite sieht es so aus, als ob Sie den Code ändern dürfen (andernfalls wie kommentieren Sie ihn aus), indem Sie eine Schnittstelle an Ihren Dienst übergeben, damit er verspottet werden kann (oder eine andere Form der Abhängigkeitsinjektion verwenden kann ).
Schließlich scheint das, was Sie testen möchten, ein reiner Wrapper um den externen Dienst zu sein. Hier gibt es fast nichts zu testen, außer dass Sie den Dienst aufrufen. Da dies im Grunde eine Schnittstelle ist, müssen die meisten Tests später auf einer höheren Ebene durchgeführt werden (Integrationstests).
quelle