Das ist etwas, das mich jetzt schon eine Weile beunruhigt. Lohnt es sich tatsächlich, einen API-Client zu testen?
Angenommen, Sie erstellen eine kleine Klasse, um die Aufrufe einer petshop-REST-API zu abstrahieren. Der Petshop ist eine sehr einfache API und verfügt über eine Reihe grundlegender Methoden:
listProducts()
getProductDetails(ProductID)
addProduct(...)
removeProduct(ProductID)
Um dies zu testen, müssten wir entweder einen Mock-Service erstellen oder die Antworten verspotten. Aber das scheint übertrieben; Ich verstehe, dass wir sicherstellen möchten, dass unsere Methoden nicht aufhören, Tipp- / Syntaxfehler zu verarbeiten, aber da wir Funktionen schreiben, die Remotemethoden aufrufen, und dann von diesen Remotemethoden gefälschte Antworten erstellen, scheint es so eine Verschwendung von Mühe und dass wir etwas testen, das nicht wirklich scheitern kann. Schlimmer noch, wenn sich die Remote-Methode ändert, bestehen unsere Komponententests, während die Produktion nicht funktioniert.
Ich bin mir ziemlich sicher, dass mir etwas fehlt, oder ich habe das falsche Ende des Stocks oder ich sehe den Wald vor lauter Bäumen nicht. Kann mich jemand auf den richtigen Weg bringen?
quelle
Antworten:
Die Aufgabe eines Remote-API-Clients besteht darin, bestimmte Aufrufe auszulösen - nicht mehr und nicht weniger. Daher sollte sein Test sicherstellen, dass er diese Anrufe ausgibt - nicht mehr und nicht weniger.
Sicher, wenn der API-Anbieter die Semantik seiner Antworten ändert, fällt Ihr System in der Produktion aus. Aber das ist nicht die Schuld Ihrer Kundenklasse. Es ist etwas, das nur in Integrationstests gefangen werden kann. Indem Sie sich auf Code verlassen, der nicht unter Ihrer Kontrolle steht, haben Sie die Möglichkeit aufgegeben, die Richtigkeit durch interne Tests zu überprüfen - es war ein Kompromiss, und das ist der Preis.
Das Testen einer Klasse, die nur aus Delegierungen an eine andere Klasse besteht, kann jedoch eine niedrige Priorität haben, da das Risiko komplexer Fehler vergleichsweise gering ist. Das gilt jedoch für jede Klasse, die nur aus einheitlichen Einzeilern besteht. Es hat nichts damit zu tun, den Code eines anderen Anbieters aufzurufen.
quelle
foo()
vorher aufgerufen wurdebar()
, aber das bedeutet nicht, dass das Anrufenfoo()
vorherbar()
richtig ist. Ein solcher Komponententest würde auch dann bestehen, wenn der Code falsch ist. Und wenn das alles ist, was der Client tut, ist es relativ mühsam , die Mocks einzurichten, die prüfen, obfoo()
er zuvor aufgerufen wurde.bar()
Dies lässt sich mit einem flüchtigen Blick auf den Clientcode überprüfen.add()
Methode zwei Zahlen korrekt addiert. Dies bedeutet jedoch nicht, dass das Addieren an dieser Stelle des Algorithmus das Richtige ist. Der Komponententestadd()
wäre erfolgreich, obwohl Ihr Programm falsch ist. Wenn es ist die falsche Sache, dann ist IhrlevenshteinDistance()
Verfahren ist schuld, nicht dasadd()
Verfahren. Das ist genau das gleiche. Bei der Aufteilung von Code in Methoden muss sich jede Methode nur darum kümmern, dass eine Sache korrekt ist.Kurze Antwort:
Alle Methoden sollten einheitlich getestet werden.
Lange Antwort:
Ja. Es lohnt sich.
Dies sind einige Dinge, die Unit-Tests für API-Aufrufmethoden testen sollten:
Dies sind Dinge, die die aufgerufene Methode tun kann, um den API-Dienst zu verspotten, und die durch gründliches Testen sicherstellen, dass Fehler nicht durch einen Fehler im Client-Code verursacht werden, der die API aufruft.
quelle
Dies wären keine Komponententests, da Sie die Ein- und Ausgabe Ihres Systems testen, eher wie eingeschränkte Integrationstests.
Seien Sie sehr vorsichtig , wenn Sie sagen , „es wie eine Verschwendung von Aufwand scheint und dass wir etwas zu test , die nicht wirklich scheitern kann“ - es fehlschlagen kann, wird es scheitern, wird es wahrscheinlich in einer Weise scheitern , dass man nicht voraussehen kann, die Fehler werden schlimmer, wenn keine Tests vorhanden sind.
Der Fehler, den Sie hier machen, hängt mit der Erfindung von Rädern zusammen: Das Aufrufen von Remotediensten und APIs ist ein sehr verbreitetes Szenario. Daher gibt es einige ziemlich gute Tools, mit denen Sie dies testen können. Als ich das letzte Mal an einer Anwendung arbeitete, die eine Verbindung zu Remotediensten herstellte, verwendete ich SoapUIDies könnte einen Dienst anzeigen und entweder Scheinaufrufe an diesen Dienst tätigen oder sich als lokale Kopie des Servers verhalten, auf dem Sie Testanrufe tätigen und die Anforderungen und Antworten nachverfolgen können. Das Einrichten dauerte Minuten und war ebenfalls sehr schnell zu aktualisieren, wenn sich die Remote-Schnittstelle änderte. Ich habe es in einem REST-Szenario nicht verwendet, aber selbst wenn es dafür nicht gut funktioniert (oder wenn es in Zukunft bessere Tools gibt, liest möglicherweise jemand diese Antwort), sollten Sie in der Lage sein, ein Tool zu finden, das sich nachahmen lässt Ein Service für Sie und wenn es Zeit ist, Ihren Code bereitzustellen, werden Sie froh sein, dass Sie es getan haben.
quelle