Was ist der beste Weg, um eine Methode zu testen, die nichts zurückgibt? Speziell in c #.
Was ich wirklich zu testen versuche, ist eine Methode, die eine Protokolldatei nimmt und sie nach bestimmten Zeichenfolgen analysiert. Die Zeichenfolgen werden dann in eine Datenbank eingefügt. Nichts, was vorher noch nicht gemacht wurde, aber ich bin sehr neu bei TDD. Ich frage mich, ob es möglich ist, dies zu testen oder ob es etwas ist, das nicht wirklich getestet wird.
c#
unit-testing
jdiaz
quelle
quelle
Antworten:
Wenn eine Methode nichts zurückgibt, ist dies eine der folgenden
Imperative Methoden - Sie können überprüfen, ob die Aufgabe tatsächlich ausgeführt wurde. Überprüfen Sie, ob tatsächlich eine Statusänderung stattgefunden hat. z.B
kann getestet werden, indem überprüft wird, ob der Kontostand nach dieser Nachricht tatsächlich unter dem Anfangswert von dAmount liegt
Informationsmethoden - sind als Mitglied der öffentlichen Schnittstelle des Objekts selten ... daher normalerweise nicht einheitlich getestet. Wenn Sie jedoch müssen, können Sie überprüfen, ob die Bearbeitung einer Benachrichtigung erfolgt. z.B
kann getestet werden, indem überprüft wird, ob die E-Mail gesendet wird
Veröffentlichen Sie weitere Details zu Ihrer tatsächlichen Methode, und die Benutzer können besser antworten.
Update : Ihre Methode macht zwei Dinge. Ich würde es tatsächlich in zwei Methoden aufteilen, die jetzt unabhängig getestet werden können.
String [] kann leicht überprüft werden, indem die erste Methode mit einer Dummy-Datei und erwarteten Strings versehen wird. Der zweite ist etwas knifflig. Sie können entweder einen Mock (Google oder Search Stackoverflow für Mocking Frameworks) verwenden, um die Datenbank nachzuahmen, oder die tatsächliche Datenbank treffen und überprüfen, ob die Zeichenfolgen an der richtigen Stelle eingefügt wurden. In diesem Thread finden Sie einige gute Bücher ... Ich würde Pragmatic Unit Testing empfehlen, wenn Sie in einer Krise stecken.
Im Code würde es wie verwendet werden
quelle
Testen Sie die Nebenwirkungen. Das beinhaltet:
Natürlich gibt es eine Grenze, wie viel Sie testen können. Sie können beispielsweise im Allgemeinen nicht mit jeder möglichen Eingabe testen. Testen Sie pragmatisch - genug, um Ihnen das Vertrauen zu geben, dass Ihr Code angemessen entworfen und korrekt implementiert ist, und genug, um als ergänzende Dokumentation für das zu dienen, was ein Anrufer erwarten könnte.
quelle
Wie immer: Testen Sie, was die Methode tun soll!
Sollte es irgendwo den globalen Zustand ändern (ähm, Codegeruch!)?
Sollte es eine Schnittstelle aufrufen?
Sollte es eine Ausnahme auslösen, wenn es mit den falschen Parametern aufgerufen wird?
Sollte es keine Ausnahme auslösen, wenn es mit den richtigen Parametern aufgerufen wird?
Sollte es ...?
quelle
Void Return-Typen / Subroutinen sind alte Nachrichten. Ich habe seit 8 Jahren keinen Void-Rückgabetyp mehr erstellt (es sei denn, ich war extrem faul) (ab dem Zeitpunkt dieser Antwort, also nur ein bisschen bevor diese Frage gestellt wurde).
Anstelle einer Methode wie:
Erstellen Sie eine Methode, die dem Paradigma int.TryParse () von Microsoft folgt:
Möglicherweise gibt es keine Informationen, die Ihre Methode zur langfristigen Verwendung zurückgeben muss, aber die Rückgabe des Status der Methode nach Ausführung ihrer Aufgabe ist für den Aufrufer eine enorme Verwendung.
Außerdem ist bool nicht der einzige Statustyp. Es gibt eine Reihe von Fällen, in denen eine zuvor erstellte Subroutine tatsächlich drei oder mehr verschiedene Zustände zurückgeben kann (Gut, Normal, Schlecht usw.). In diesen Fällen würden Sie nur verwenden
Während das Try-Paradigma diese Frage zum Testen einer ungültigen Rückgabe etwas beantwortet, gibt es auch andere Überlegungen. Während / nach einem "TDD" -Zyklus würden Sie beispielsweise "Refactoring" durchführen und feststellen, dass Sie mit Ihrer Methode zwei Dinge tun ... und damit das "Prinzip der Einzelverantwortung" brechen. Das sollte also zuerst erledigt werden. Zweitens haben Sie möglicherweise eine Abhängigkeit identifiziert ... Sie berühren "Persistente" Daten.
Wenn Sie den Datenzugriff in der betreffenden Methode ausführen, müssen Sie eine Umgestaltung in eine n-Tier- oder n-Layer-Architektur vornehmen. Wir können jedoch davon ausgehen, dass Sie mit "Die Zeichenfolgen werden dann in eine Datenbank eingefügt" tatsächlich eine Geschäftslogikschicht oder etwas anderes aufrufen. Ja, das nehmen wir an.
Wenn Ihr Objekt instanziiert wird, verstehen Sie jetzt, dass Ihr Objekt Abhängigkeiten aufweist. In diesem Fall müssen Sie entscheiden, ob Sie eine Abhängigkeitsinjektion für das Objekt oder für die Methode durchführen möchten. Das bedeutet, dass Ihr Konstruktor oder die betreffende Methode einen neuen Parameter benötigt:
Jetzt, da Sie eine Schnittstelle Ihres Geschäfts- / Datenebenenobjekts akzeptieren können, können Sie diese während der Komponententests verspotten und haben keine Abhängigkeiten oder Angst vor "versehentlichen" Integrationstests.
In Ihrem Live-Code übergeben Sie also ein REAL-
IBusinessDataEtc
Objekt. Bei Ihrem Unit-Test übergeben Sie jedoch ein MOCK-IBusinessDataEtc
Objekt. In diesem Mock können Sie Nicht-Schnittstelleneigenschaften wieint XMethodWasCalledCount
oder etwas einschließen , dessen Status beim Aufruf der Schnittstellenmethoden aktualisiert werden.Ihr Unit-Test geht also Ihre fraglichen Methoden durch, führt die jeweils vorhandene Logik aus und ruft eine oder zwei oder einen ausgewählten Satz von Methoden in Ihrem
IBusinessDataEtc
Objekt auf. Wenn Sie Ihre Aussagen am Ende Ihres Unit-Tests machen, müssen Sie jetzt einige Dinge testen.IBusinessDataEtc
Objekts.Weitere Informationen zu Ideen für die Abhängigkeitsinjektion auf Konstruktionsebene ... in Bezug auf Unit-Tests ... finden Sie in den Builder-Entwurfsmustern. Es fügt eine weitere Schnittstelle und Klasse für jede aktuelle Schnittstelle / Klasse hinzu, die Sie haben, aber sie sind sehr klein und bieten RIESIGE Funktionserweiterungen für bessere Unit-Tests.
quelle
public void sendEmailToCustomer() throws UndeliveredMailException
?void
Methoden, insbesondere in objektorientierten Sprachen, war dies jedoch die einzige echte Option. Die älteste Alternative von Microsoft ist das von mir diskutierte Try-Paradigma und Paradigmen im funktionalen Stil wie Monaden / Maybes. Auf diese Weise können Befehle (in CQS) weiterhin wertvolle Statusinformationen zurückgeben, anstatt sich auf das Werfen zu verlassen, das einem ähnlich istGOTO
(von dem wir wissen, dass es schlecht ist). Werfen (und gehen) sind langsam, schwer zu debuggen und keine gute Übung.Versuche dies:
quelle
ExpectedAttribute
soll diesen Test deutlicher machen.Sie können es sogar so versuchen:
quelle
Dies hat Auswirkungen auf ein Objekt .... Abfrage des Ergebnisses des Effekts. Wenn es keine sichtbare Wirkung hat, lohnt es sich nicht, es zu testen!
quelle
Vermutlich macht die Methode etwas und kehrt nicht einfach zurück?
Angenommen, dies ist der Fall, dann:
Wenn Sie uns mitteilen, was die Methode bewirkt, könnte ich genauer sein.
quelle
Verwenden Sie Rhino Mocks , um festzulegen , welche Aufrufe, Aktionen und Ausnahmen zu erwarten sind. Angenommen, Sie können Teile Ihrer Methode verspotten oder ausstechen. Schwer zu wissen, ohne hier einige Einzelheiten über die Methode oder sogar den Kontext zu kennen.
quelle
Kommt darauf an, was es macht. Wenn es Parameter enthält, übergeben Sie Mocks, die Sie später fragen können, ob sie mit dem richtigen Parametersatz aufgerufen wurden.
quelle
Welche Instanz auch immer Sie verwenden, um die void-Methode aufzurufen, Sie können einfach Folgendes verwenden:
Verfiy
Beispielsweise:
In meinem Fall
_Log
ist es die Instanz undLogMessage
die zu testende Methode:Ist das
Verify
Auslösen eine Ausnahme aufgrund eines Fehlers der Methode, bei der der Test fehlschlagen würde?quelle