Ein Beispiel für einen Fehlerfall, den Sie gerne abfangen würden, besteht darin, dass das zu testende Objekt eine Caching-Ebene verwendet, die Daten jedoch nicht wie erforderlich beibehalten. Wenn Sie das Objekt dann abfragen, wird angezeigt: "Ja, ich habe den neuen Namen und die neue Adresse". Sie möchten jedoch, dass der Test fehlschlägt, da er nicht genau das getan hat, was er eigentlich sollte.
Alternativ (und mit Blick auf die Verletzung der Einzelverantwortung) wird angenommen, dass eine UTF-8-codierte Version der Zeichenfolge in einem byteorientierten Feld beibehalten werden muss, Shift JIS jedoch beibehalten wird. Eine andere Komponente wird die Datenbank lesen und erwartet, dass UTF-8 angezeigt wird, daher die Anforderung. Bei der Rundreise durch dieses Objekt werden dann der richtige Name und die richtige Adresse gemeldet, da sie von Shift JIS zurückkonvertiert werden. Der Fehler wird jedoch von Ihrem Test nicht erkannt. Es wird hoffentlich durch einen späteren Integrationstest erkannt, aber der springende Punkt bei Unit-Tests ist, Probleme frühzeitig zu erkennen und genau zu wissen, welche Komponente dafür verantwortlich ist.
Wenn einer von ihnen nicht tut, was er tun soll, schlägt sein eigener Testfall fehl und wir können ihn beheben und die Testbatterie erneut ausführen.
Das können Sie nicht annehmen, denn wenn Sie nicht aufpassen, schreiben Sie eine Reihe von Tests, die sich gegenseitig bedingen. Das "spart es?" test ruft die Speichermethode auf, die getestet wird, und anschließend die Lademethode, um das Speichern zu bestätigen. Das "lädt es?" test ruft die Speichermethode auf, um das Testgerät einzurichten, und dann die Lademethode, die es testet, um das Ergebnis zu überprüfen. Beide Tests stützen sich auf die Richtigkeit der Methode, die sie nicht testen, dh, keiner von beiden testet tatsächlich die Richtigkeit der Methode, die er testet.
Der Hinweis, dass es hier ein Problem gibt, ist, dass zwei Tests, die angeblich verschiedene Einheiten testen, tatsächlich dasselbe tun . Beide rufen einen Setter gefolgt von einem Getter auf und prüfen dann, ob das Ergebnis der ursprüngliche Wert ist. Sie wollten jedoch testen, ob der Setter die Daten beibehält, und nicht, ob das Setter / Getter-Paar zusammenarbeitet. Damit Sie wissen, dass etwas nicht stimmt, müssen Sie nur herausfinden, was passiert, und die Tests korrigieren.
Wenn Ihr Code für Komponententests gut konzipiert ist, können Sie auf mindestens zwei Arten testen, ob die Daten von der getesteten Methode wirklich korrekt beibehalten wurden:
Verspotten Sie die Datenbankschnittstelle, und lassen Sie Ihre Verspottung die Tatsache aufzeichnen, dass die richtigen Funktionen mit den erwarteten Werten aufgerufen wurden. Dies testet die Methode, was es soll, und ist der klassische Unit-Test.
Übergeben Sie ihm eine aktuelle Datenbank mit genau der gleichen Absicht , um aufzuzeichnen, ob die Daten korrekt gespeichert wurden oder nicht. Aber anstatt eine verspottete Funktion zu haben, die nur sagt "Ja, ich habe die richtigen Daten", liest Ihr Test direkt aus der Datenbank zurück und bestätigt, dass er korrekt ist. Dies ist möglicherweise nicht der reinste Test, da eine gesamte Datenbank-Engine eine ziemlich große Sache ist, um einen verherrlichten Schein zu schreiben, wobei ich mit größerer Wahrscheinlichkeit eine Feinheit übersehen kann, die einen Test bestanden hat, obwohl etwas nicht stimmt (also zum Beispiel ich) sollte nicht dieselbe Datenbankverbindung zum Lesen verwenden, die zum Schreiben verwendet wurde, da möglicherweise eine nicht festgeschriebene Transaktion angezeigt wird. Aber es testet das Richtige, und zumindest weißt du, dass es genau ist implementiert die gesamte Datenbankschnittstelle, ohne dass ein Mock-Code geschrieben werden muss!
Es ist also nur ein Detail der Testimplementierung, ob ich die Daten von JDBC aus der Testdatenbank lese oder ob ich die Datenbank verspotte. In beiden Fällen kann ich das Gerät besser testen, indem ich es isoliere, als wenn ich zulasse, dass es mit anderen falschen Methoden in derselben Klasse konspiriert, um auch dann richtig auszusehen, wenn etwas nicht stimmt. Aus diesem Grund möchte ich auf bequeme Weise überprüfen, ob die korrekten Daten erhalten geblieben sind, und nicht der Komponente vertrauen, deren Methode ich teste.
Wenn Ihr Code nicht für Komponententests geeignet ist, haben Sie möglicherweise keine andere Wahl, da das Objekt, dessen Methode Sie testen möchten, die Datenbank möglicherweise nicht als injizierte Abhängigkeit akzeptiert. In diesem Fall ändert sich die Diskussion über den besten Weg, das zu testende Gerät zu isolieren, in eine Diskussion darüber, wie nahe es möglich ist, das zu testende Gerät zu isolieren. Die Schlussfolgerung ist jedoch die gleiche. Wenn Sie Verschwörungen zwischen fehlerhaften Einheiten vermeiden können, können Sie, vorbehaltlich der verfügbaren Zeit und aller anderen Faktoren, die Sie für effektiver halten, Fehler im Code finden.