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:
public void SendEmailToCustomer()
Erstellen Sie eine Methode, die dem Paradigma int.TryParse () von Microsoft folgt:
public bool TrySendEmailToCustomer()
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
public StateEnum TrySendEmailToCustomer()
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:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
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 wie int 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.
- Der Zustand der "Subroutine", die jetzt eine Try-Paradigm-Methode ist.
- Der Status Ihres Mock-
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.