In unserem Team wird derzeit diskutiert, ob das Ändern des Code-Designs, um das Testen von Einheiten zu ermöglichen, ein Codegeruch ist oder inwieweit dies ohne Codegeruch möglich ist. Dies ist darauf zurückzuführen, dass wir gerade erst damit beginnen, Praktiken einzuführen, die in nahezu jedem anderen Softwareentwicklungsunternehmen vorhanden sind.
Insbesondere werden wir einen Web-API-Dienst haben, der sehr dünn sein wird. Seine Hauptaufgabe besteht darin, Webanforderungen / -antworten zusammenzustellen und eine zugrunde liegende API aufzurufen, die die Geschäftslogik enthält.
Ein Beispiel ist, dass wir eine Factory erstellen möchten, die einen Authentifizierungsmethodentyp zurückgibt. Wir müssen keine Schnittstelle erben, da wir nicht davon ausgehen, dass es jemals etwas anderes als die konkrete Art sein wird, die es sein wird. Zum Testen des Web-API-Dienstes müssen wir uns jedoch über diese Factory lustig machen.
Dies bedeutet im Wesentlichen, dass wir entweder die Web-API-Controller-Klasse so entwerfen, dass sie DI akzeptiert (über ihren Konstruktor oder Setter). Dies bedeutet, dass wir einen Teil des Controllers so entwerfen, dass DI zugelassen wird und eine Schnittstelle implementiert wird, die wir sonst nicht benötigen, oder dass wir sie verwenden ein Framework eines Drittanbieters wie Ninject, um zu vermeiden, dass der Controller auf diese Weise entworfen werden muss, aber wir müssen immer noch eine Schnittstelle erstellen.
Einige im Team scheinen nur zu Testzwecken ungern Code zu entwerfen. Es scheint mir, dass es Kompromisse geben muss, wenn Sie auf einen Unit-Test hoffen, aber ich bin mir nicht sicher, wie sie ihre Bedenken zerstreuen können.
Dies ist ein brandneues Projekt. Es geht also nicht wirklich darum, Code zu ändern, um Unit-Tests zu ermöglichen. Es geht darum, den Code, den wir schreiben werden, so zu gestalten, dass er für Einheiten testbar ist.
Antworten:
Die Zurückhaltung, Code für Testzwecke zu ändern, zeigt, dass ein Entwickler die Rolle von Tests und implizit die eigene Rolle in der Organisation nicht verstanden hat.
Das Software-Geschäft dreht sich darum, eine Codebasis bereitzustellen, die geschäftlichen Wert schafft. Wir haben durch langjährige und erbitterte Erfahrung festgestellt, dass wir solche Codebasen von nicht-trivialer Größe nicht ohne Tests erstellen können. Daher sind Testsuiten ein wesentlicher Bestandteil des Geschäfts.
Viele Programmierer bekennen sich zu diesem Prinzip, akzeptieren es jedoch unbewusst nie. Es ist leicht zu verstehen, warum dies so ist; Das Bewusstsein, dass unsere eigenen mentalen Fähigkeiten nicht unendlich sind und in der Tat überraschend begrenzt sind, wenn wir mit der enormen Komplexität einer modernen Codebasis konfrontiert werden, ist unerwünscht und kann leicht unterdrückt oder rationalisiert werden. Die Tatsache, dass der Testcode nicht an den Kunden ausgeliefert wird, lässt vermuten, dass er ein Bürger zweiter Klasse ist und im Vergleich zum "wesentlichen" Geschäftscode nicht wesentlich ist. Und die Idee , dem Geschäftscode Testcode hinzuzufügen, wirkt sich für viele doppelt beleidigend aus.
Die Schwierigkeit, diese Praxis zu rechtfertigen, hat damit zu tun, dass das gesamte Bild der Wertschöpfung in einem Software-Geschäft oft nur von höheren Stellen in der Unternehmenshierarchie verstanden wird, aber diese Personen haben kein detailliertes technisches Verständnis dafür der Codierungsworkflow, der erforderlich ist, um zu verstehen, warum das Testen nicht abgeschafft werden kann. Deshalb werden sie zu oft von Praktizierenden befriedet, die ihnen versichern, dass das Testen im Allgemeinen eine gute Idee ist, aber "Wir sind Elite-Programmierer, die solche Krücken nicht brauchen", oder "dafür haben wir momentan keine Zeit", usw. usw. Die Tatsache, dass geschäftlicher Erfolg ein Spiel mit Zahlen ist und die Vermeidung von technischen Schulden Qualität etc. zeigt ihren Wert nur auf längere Sicht, was bedeutet, dass sie diesem Glauben oft sehr aufrichtig gegenüberstehen.
Kurz gesagt: Code testbar zu machen ist ein wesentlicher Bestandteil des Entwicklungsprozesses, nicht anders als in anderen Bereichen (viele Mikrochips sind nur zu Testzwecken mit einem erheblichen Anteil an Elementen entworfen ), aber es ist sehr leicht, die sehr guten Gründe dafür zu übersehen Das. Fallen Sie nicht in diese Falle.
quelle
Es ist nicht so einfach, wie Sie vielleicht denken. Lassen Sie es uns aufschlüsseln.
ABER!
Jede Änderung an Ihrem Code kann einen Fehler verursachen. Eine Änderung des Codes ohne guten Geschäftsgrund ist daher keine gute Idee.
Ihr 'sehr dünnes' Webapi scheint nicht der beste Fall für Unit-Tests zu sein.
Das gleichzeitige Ändern von Code und Tests ist eine schlechte Sache.
Ich würde den folgenden Ansatz vorschlagen:
Schreiben Sie Integrationstests . Dies sollte keine Codeänderungen erfordern. Sie erhalten eine Übersicht über Ihre grundlegenden Testfälle und können überprüfen, ob weitere Codeänderungen keine Fehler verursachen.
Stellen Sie sicher, dass neuer Code testbar ist und Unit- und Integrationstests enthält.
Stellen Sie sicher, dass Ihre CI-Kette nach Builds und Bereitstellungen Tests ausführt.
Wenn Sie diese Dinge eingerichtet haben, sollten Sie erst darüber nachdenken, ältere Projekte auf ihre Testbarkeit hin zu überarbeiten.
Hoffentlich hat jeder aus dem Prozess Lehren gezogen und hat eine gute Vorstellung davon, wo das Testen am dringendsten erforderlich ist, wie Sie es strukturieren möchten und welchen Nutzen es für das Unternehmen bringt.
EDIT : Seit ich diese Antwort geschrieben habe, hat das OP die Frage geklärt, um zu zeigen, dass es sich um neuen Code handelt, nicht um Änderungen an vorhandenem Code. Ich dachte vielleicht naiv: "Ist der Gerätetest gut?" Streit wurde vor einigen Jahren beigelegt.
Es ist schwer vorstellbar, welche Codeänderungen für Komponententests erforderlich wären, aber keine allgemein bewährte Vorgehensweise, die Sie auf jeden Fall wünschen würden. Es wäre wahrscheinlich ratsam, die tatsächlichen Einwände zu untersuchen, möglicherweise ist es die Art des Unit-Tests, die beanstandet wird.
quelle
Das Entwerfen von Code als inhärent testbar ist kein Codegeruch. im Gegenteil, es ist das Zeichen eines guten Designs. Es gibt mehrere bekannte und weit verbreitete Entwurfsmuster (z. B. Model-View-Presenter), die ein einfaches (leichteres) Testen als großen Vorteil bieten.
Wenn Sie also eine Schnittstelle für Ihre konkrete Klasse schreiben müssen, um sie einfacher testen zu können, ist das eine gute Sache. Wenn Sie die konkrete Klasse bereits haben, können die meisten IDEs eine Schnittstelle daraus extrahieren, wodurch der erforderliche Aufwand minimal ist. Es ist ein bisschen mehr Arbeit, die beiden synchron zu halten, aber eine Benutzeroberfläche sollte sich sowieso nicht wesentlich ändern, und die Vorteile des Testens können diesen zusätzlichen Aufwand aufwiegen.
Andererseits als @MatthieuM. Erwähnt in einem Kommentar: Wenn Sie Ihrem Code bestimmte Einstiegspunkte hinzufügen, die in der Produktion niemals verwendet werden sollten, nur zum Testen, könnte dies ein Problem darstellen.
quelle
_ForTest
) und überprüfen Sie die Codebasis auf Aufrufe von Nicht-Test-Code.Es ist meiner Meinung nach sehr einfach zu verstehen, dass der zu testende Code zum Erstellen von Komponententests mindestens bestimmte Eigenschaften haben muss. Wenn der Code beispielsweise nicht aus einzelnen Einheiten besteht, die einzeln getestet werden können, ergibt das Wort "Einheitentest" nicht einmal einen Sinn. Wenn der Code diese Eigenschaften nicht hat, muss er zuerst geändert werden, das ist ziemlich offensichtlich.
Theoretisch kann man versuchen, zuerst eine testbare Code-Einheit zu schreiben, indem man alle SOLID-Prinzipien anwendet, und anschließend versuchen, einen Test dafür zu schreiben, ohne den ursprünglichen Code weiter zu modifizieren. Leider ist das Schreiben von Code, der wirklich in einer Einheit testbar ist, nicht immer kinderleicht. Es ist daher sehr wahrscheinlich, dass einige Änderungen erforderlich sind, die nur beim Erstellen der Tests erkannt werden. Dies gilt für Code, selbst wenn er mit dem Gedanken an Unit-Tests geschrieben wurde, und auf jeden Fall mehr für Code, der geschrieben wurde, als "Unit-Testbarkeit" am Anfang nicht auf der Tagesordnung stand.
Es gibt einen bekannten Ansatz, der versucht, das Problem zu lösen, indem zuerst die Komponententests geschrieben werden. Er heißt Test Driven Development (TDD) und kann sicherlich dazu beitragen, den Code von Anfang an testbarer zu machen.
Natürlich tritt die Zurückhaltung, Code später zu ändern, um ihn testbar zu machen, häufig in einer Situation auf, in der der Code zuerst manuell getestet wurde und / oder in der Ausführung einwandfrei funktioniert, so dass das Ändern tatsächlich neue Fehler hervorrufen kann, das stimmt. Der beste Ansatz, um dies zu verringern, besteht darin, zuerst eine Regressionstestsuite zu erstellen (die häufig mit nur sehr geringen Änderungen an der Codebasis implementiert werden kann) sowie andere begleitende Maßnahmen wie Codeüberprüfungen oder neue manuelle Testsitzungen. Das sollten Sie tun, um sicherzugehen, dass die Neugestaltung einiger Interna nichts Wichtiges kaputt macht.
quelle
Ich bezweifle Ihre (unbegründete) Behauptung:
Das ist nicht unbedingt wahr. Es gibt viele Möglichkeiten, Tests zu schreiben, und es gibt Möglichkeiten, Komponententests zu schreiben, die keine Verspottungen beinhalten. Noch wichtiger ist, dass es andere Arten von Tests gibt, beispielsweise Funktions- oder Integrationstests. Oft ist es möglich, eine "Testnaht" an einer "Schnittstelle" zu finden, die keine OOP-Programmiersprache ist
interface
.Einige Fragen, die Ihnen helfen sollen, eine alternative Testnaht zu finden, die natürlicher sein könnte:
Eine weitere unbegründete Behauptung, die Sie aufstellen, betrifft DI:
Abhängigkeitsinjektion bedeutet nicht notwendigerweise, eine neue zu erstellen
interface
. Zum Beispiel wegen eines Authentifizierungstokens: Können Sie ein echtes Authentifizierungstoken einfach programmgesteuert erstellen ? Dann kann der Test solche Token erzeugen und injizieren. Hängt der Prozess zur Validierung eines Tokens von einem kryptografischen Geheimnis ab? Ich hoffe, Sie haben kein Geheimnis fest codiert - ich würde erwarten, dass Sie es irgendwie aus dem Speicher lesen können, und in diesem Fall können Sie einfach ein anderes (bekanntes) Geheimnis in Ihren Testfällen verwenden.Dies soll nicht heißen, dass Sie niemals ein neues erstellen sollten
interface
. Aber lassen Sie sich nicht darauf fixieren, dass es nur eine Möglichkeit gibt, einen Test zu schreiben oder ein Verhalten vorzutäuschen. Wenn Sie über den Tellerrand hinaus denken, finden Sie normalerweise eine Lösung, die ein Minimum an Codeverfälschungen erfordert und Ihnen dennoch den gewünschten Effekt verleiht.quelle
Sie haben Glück, denn dies ist ein neues Projekt. Ich habe festgestellt, dass Test Driven Design sehr gut zum Schreiben von gutem Code geeignet ist (weshalb wir es in erster Linie tun).
Indem Sie im Voraus herausfinden , wie ein bestimmtes Stück Code mit realistischen Eingabedaten aufgerufen und dann realistische Ausgabedaten abgerufen werden, die Sie wie beabsichtigt überprüfen können, erstellen Sie das API-Design sehr früh im Prozess und haben eine gute Chance, eine zu erhalten Nützliches Design, da Sie nicht durch vorhandenen Code behindert werden, der für die Anpassung neu geschrieben werden muss. Außerdem ist es für Ihre Kollegen einfacher zu verstehen, sodass Sie frühzeitig wieder gute Diskussionen führen können.
Beachten Sie, dass "nützlich" im obigen Satz nicht nur bedeutet, dass die resultierenden Methoden leicht aufzurufen sind, sondern auch, dass Sie dazu neigen, saubere Schnittstellen zu erhalten, die sich in Integrationstests leicht aufrüsten lassen und für die Sie Modelle schreiben können.
Denke darüber nach. Vor allem mit Peer Review. Meiner Erfahrung nach macht sich der Aufwand sehr schnell bezahlt.
quelle
UserCanChangeTheirPassword
, rufen Sie im Test die (noch nicht vorhandene) Funktion auf, um das Kennwort zu ändern, und bestätigen dann, dass das Kennwort tatsächlich geändert wurde. Dann schreiben Sie die Funktion, bis Sie den Test ausführen können und er weder Ausnahmen auslöst noch eine falsche Behauptung hat. Wenn Sie zu diesem Zeitpunkt einen Grund haben, Code hinzuzufügen, wird dieser Grund in einen anderen Test übernommen, zUserCantChangePasswordToEmptyString
.CalculateFactorial
, die nur 120 zurückgibt und den Test besteht. Das ist das Minimum. Es ist auch offensichtlich nicht das, was beabsichtigt war, aber das nur bedeutet , dass Sie einen anderen Test benötigen um auszudrücken , was wurde gedacht.Wenn Sie den Code ändern müssen, ist dies der Codegeruch.
Aus persönlicher Erfahrung ist mein Code schlecht, wenn es schwierig ist, Tests für ihn zu schreiben. Es ist kein schlechter Code, weil er nicht wie geplant ausgeführt wird oder funktioniert. Es ist schlecht, weil ich nicht so schnell verstehen kann, warum er funktioniert. Wenn ich auf einen Fehler stoße, weiß ich, dass es lange dauern wird, bis ich ihn behebe. Es ist auch schwierig / unmöglich, den Code wiederzuverwenden.
Guter (sauberer) Code unterteilt Aufgaben in kleinere Abschnitte, die auf einen Blick leicht zu verstehen sind (oder zumindest gut aussehen). Das Testen dieser kleineren Abschnitte ist einfach. Ich kann auch Tests schreiben, die nur dann einen Teil der Codebasis mit ähnlicher Leichtigkeit testen, wenn ich mir der Unterabschnitte ziemlich sicher bin (hier hilft auch die Wiederverwendung, da sie bereits getestet wurde).
Halten Sie den Code von Anfang an einfach zu testen, zu überarbeiten und wiederzuverwenden, und Sie werden sich nicht selbst umbringen, wenn Sie Änderungen vornehmen müssen.
Ich schreibe dies, während ich ein Projekt, das ein wegwerfbarer Prototyp sein sollte, vollständig in saubereren Code umbaue. Es ist viel besser, es von Anfang an richtig zu machen und schlechten Code so schnell wie möglich umzugestalten, als stundenlang auf einen Bildschirm zu starren und Angst zu haben, irgendetwas zu berühren, aus Angst, etwas zu beschädigen, das teilweise funktioniert.
quelle
Ich würde argumentieren, dass das Schreiben von Code, der nicht Unit-getestet werden kann, ein Codegeruch ist. Wenn Ihr Code nicht Unit-getestet werden kann, ist er im Allgemeinen nicht modular, was das Verstehen, Verwalten oder Verbessern erschwert. Handelt es sich bei dem Code möglicherweise um Glue-Code, der nur im Hinblick auf Integrationstests sinnvoll ist, können Sie Integrationstests durch Komponententests ersetzen. Aber selbst dann, wenn die Integration fehlschlägt, müssen Sie das Problem eingrenzen, und Komponententests sind ein guter Weg, dies zu erreichen Tu es.
Du sagst
Ich folge dem nicht wirklich. Der Grund für eine Fabrik, die etwas erstellt, besteht darin, dass Sie Fabriken oder das, was die Fabrik erstellt, problemlos ändern können, sodass andere Teile des Codes nicht geändert werden müssen. Wenn sich Ihre Authentifizierungsmethode niemals ändern wird, ist die Werkseinstellung unbrauchbar. Wenn Sie jedoch im Test eine andere Authentifizierungsmethode als in der Produktion verwenden möchten, ist eine Factory, die im Test eine andere Authentifizierungsmethode als in der Produktion zurückgibt, eine gute Lösung.
Sie brauchen dafür weder DI noch Mocks. Sie müssen lediglich die verschiedenen Authentifizierungstypen in Ihrer Factory unterstützen und diese irgendwie konfigurieren, z. B. anhand einer Konfigurationsdatei oder einer Umgebungsvariablen.
quelle
In jeder Ingenieurdisziplin, die mir einfällt, gibt es nur einen Weg, um ein angemessenes oder höheres Qualitätsniveau zu erreichen:
Zur Berücksichtigung von Inspektionen / Tests im Design.
Dies gilt für Konstruktion, Chip-Design, Software-Entwicklung und Fertigung. Dies bedeutet nicht, dass das Testen die Säule ist, auf der jedes Design aufgebaut sein muss, und überhaupt nicht. Bei jeder Konstruktionsentscheidung müssen die Konstrukteure jedoch die Auswirkungen auf die Testkosten klar erkennen und bewusste Entscheidungen über den Kompromiss treffen.
In einigen Fällen sind manuelle oder automatisierte Tests (z. B. Selen) praktischer als Komponententests, bieten aber auch eine akzeptable Testabdeckung für sich. In seltenen Fällen kann es auch akzeptabel sein, etwas fast Ungetestetes hinauszuwerfen. Diese müssen jedoch von Fall zu Fall bewusst sein. Das Aufrufen eines Designs, bei dem ein "Codegeruch" getestet wird, weist auf einen schwerwiegenden Mangel an Erfahrung hin.
quelle
Ich habe festgestellt, dass Unit-Tests (und andere Arten von automatisierten Tests) dazu neigen, Code-Gerüche zu reduzieren, und ich kann mir kein einziges Beispiel vorstellen, in dem sie Code-Gerüche einführen. Unit-Tests zwingen Sie normalerweise dazu, besseren Code zu schreiben. Wenn Sie eine im Test befindliche Methode nicht problemlos verwenden können, warum sollte es in Ihrem Code einfacher sein?
Gut geschriebene Unit-Tests zeigen Ihnen, wie der Code verwendet werden soll. Sie sind eine Form von ausführbarer Dokumentation. Ich habe abscheulich geschriebene, zu lange Komponententests gesehen, die einfach nicht verstanden werden konnten. Schreiben Sie diese nicht! Wenn Sie lange Tests schreiben müssen, um Ihre Klassen einzurichten, müssen Ihre Klassen überarbeitet werden.
Unit-Tests werden aufzeigen, wo einige Ihrer Code-Gerüche sind. Ich würde empfehlen, Michael C. Feathers ' Arbeiten mit Legacy Code effektiv zu lesen . Auch wenn Ihr Projekt neu ist, müssen Sie möglicherweise einige nicht offensichtliche Techniken anwenden, um den Code ordnungsgemäß zu testen, wenn es noch keine (oder viele) Komponententests enthält.
quelle
In einer Nussschale:
Testbarer Code ist (normalerweise) wartbarer Code - oder besser gesagt, schwer zu testender Code ist normalerweise schwer zu warten. Designing Code, der nicht prüfbar ist verwandt mit der Gestaltung einer Maschine, die nicht reparierbar ist - schade , dass der arme shmuck , die wird es zugeordnet zu reparieren schließlich (es kann ihnen sein).
Sie wissen, dass Sie in drei Jahren fünf verschiedene Arten von Authentifizierungsmethoden benötigen werden, jetzt, wo Sie das gesagt haben, richtig? Die Anforderungen ändern sich, und während Sie ein Überarbeiten Ihres Designs vermeiden sollten, bedeutet ein testbares Design, dass Ihr Design (gerade) genug Nähte hat, um ohne (zu viel) Schmerz geändert zu werden - und dass die Modultests Ihnen automatisierte Mittel bieten, um dies zu erkennen Ihre Änderungen machen nichts kaputt.
quelle
Das Entwerfen mit Abhängigkeitsinjektion ist kein Codegeruch - es ist eine bewährte Methode. Die Verwendung von DI dient nicht nur der Testbarkeit. Wenn Sie Ihre Komponenten auf DI aufbauen, werden Modularität und Wiederverwendbarkeit unterstützt. Dies erleichtert das Auslagern wichtiger Komponenten (z. B. einer Datenbankschnittstellenschicht). Durch die richtige Ausführung wird zwar ein gewisses Maß an Komplexität hinzugefügt, die Trennung der Ebenen und die Isolation der Funktionen werden jedoch erleichtert, sodass die Komplexität einfacher verwaltet und navigiert werden kann. Dies erleichtert die ordnungsgemäße Überprüfung des Verhaltens der einzelnen Komponenten, wodurch Fehler reduziert und das Aufspüren von Fehlern vereinfacht werden.
quelle
Schauen wir uns den Unterschied zwischen einem testbaren an:
und nicht testbarer Controller:
Die erste Option enthält buchstäblich 5 zusätzliche Codezeilen, von denen zwei von Visual Studio automatisch generiert werden können. Sobald Sie Ihr Abhängigkeitsinjektionsframework so eingerichtet haben, dass es
IMyDependency
zur Laufzeit einen konkreten Typ ersetzt - was für jedes anständige DI-Framework eine weitere einzelne Codezeile darstellt -, funktioniert alles, außer dass Sie jetzt Ihren Controller nach Herzenslust verspotten und testen können .6 zusätzliche Codezeilen, um die Testbarkeit zu gewährleisten ... und Ihre Kollegen argumentieren, das sei "zu viel Arbeit"? Dieses Argument passt nicht zu mir und sollte auch nicht zu dir passen.
Und Sie müssen keine Schnittstelle zum Testen erstellen und implementieren: Mit Moq können Sie beispielsweise das Verhalten eines konkreten Typs zu Zwecken des Komponententests simulieren. Das wird Ihnen natürlich nicht viel nützen, wenn Sie diese Typen nicht in die Klassen einspeisen können, die Sie testen.
Die Abhängigkeitsinjektion ist eines der Dinge, die Sie sich fragen, wenn Sie sie erst einmal verstanden haben: "Wie habe ich ohne sie gearbeitet?". Es ist einfach, es ist effektiv und es macht nur Sinn. Bitte lassen Sie nicht zu, dass das mangelnde Verständnis Ihrer Kollegen für neue Dinge die Testbarkeit Ihres Projekts beeinträchtigt.
quelle
Wenn ich Unit-Tests schreibe, beginne ich zu überlegen, was in meinem Code schief gehen könnte. Es hilft mir, das Code-Design zu verbessern und das Single-Responsibility-Prinzip (SRP) anzuwenden . Wenn ich einige Monate später wieder zurückkomme, um denselben Code zu ändern, kann ich feststellen, dass die vorhandene Funktionalität nicht beschädigt ist.
Es gibt einen Trend, reine Funktionen so oft wie möglich zu verwenden (serverlose Apps). Unit-Tests helfen mir, Zustände zu isolieren und reine Funktionen zu schreiben.
Schreiben Sie zuerst Komponententests für die zugrunde liegende API. Wenn Sie genügend Entwicklungszeit haben, müssen Sie auch Tests für den Thin-Web-API-Service schreiben.
TL; DR, Komponententests tragen zur Verbesserung der Codequalität bei und tragen dazu bei, zukünftige Änderungen am Code ohne Risiko durchzuführen. Es verbessert auch die Lesbarkeit des Codes. Verwenden Sie Tests anstelle von Kommentaren, um Ihren Standpunkt zu verdeutlichen.
quelle
Das Fazit und was sollte Ihr Argument mit dem zögernden Los sein, ist, dass es keinen Konflikt gibt. Der große Fehler scheint gewesen zu sein, dass jemand die Idee geprägt hat, Menschen, die das Testen hassen, "zum Testen zu designen". Sie hätten einfach den Mund halten oder es anders ausdrücken sollen, wie "Nehmen wir uns die Zeit, dies richtig zu machen".
Die Idee, dass "Sie eine Schnittstelle implementieren müssen", um etwas testbar zu machen, ist falsch. Das Interface ist bereits implementiert, es ist nur noch nicht in der Klassendeklaration deklariert. Es geht darum, vorhandene öffentliche Methoden zu erkennen, ihre Signaturen in eine Schnittstelle zu kopieren und diese Schnittstelle in der Klassendeklaration zu deklarieren. Keine Programmierung, keine Änderungen an der vorhandenen Logik.
Anscheinend haben einige Leute eine andere Vorstellung davon. Ich schlage vor, Sie versuchen, dies zuerst zu beheben.
quelle