Nachdem ich einige Artikel über Newable vs Injectable- Objekte gelesen hatte und wie sich diese Konzepte auf die Dienste, Entitäten und Wertobjekte von DDD beziehen, hatte ich einige Zweifel an der Verwendung von Newables in meinem Code, insbesondere in meinen Komponententests.
Hauptkandidaten für neue Objekte waren Entities- und Value-Objekte, dh anstatt diese Abhängigkeiten in andere Objekte einzufügen, sollte man nur new
eine Instanz dieser Objekte verwenden und sie direkt im Code verwenden.
Gute DDD-Praktiken empfehlen jedoch, Entitäten Verantwortlichkeiten zuzuweisen und Objekte zu bewerten, wenn dies als angemessen erachtet wird. Die Entitäten und Wertobjekte werden also keine ernsthafte Geschäftslogik mehr enthalten.
Wenn ein Dienst nun mit einer Entität oder einem Wertobjekt arbeitet, sollte ich die Entität oder das Wertobjekt verspotten und das Verspotten an den Dienst übergeben ( interface
für das Verspotten ist ein Wert für die Wertobjekte oder Entitäten erforderlich, gegen die anscheinend gesprochen wird)?
Oder sollte ich nur new
ein Entitäts- / Wertobjekt sein und eine konkrete Implementierung an den Service übergeben und damit gegen das Unit-Test-Prinzip verstoßen, nur eine Einheit zu testen?
Antworten:
Ich lese, dass Sie der Meinung sind, dass Unit-Tests, ähnlich wie SOLID-Objekte, "einen Grund zum Brechen" haben müssen. Es ist ein nobles Ziel, aber ich denke, Sie werden feststellen, dass es in vielen Fällen einfach nicht machbar ist. In einem dieser Fälle haben Sie ein "reichhaltiges" Domänenobjekt (DDD unterscheidet zwischen Entitäten und Wertobjekten, die beide das "Domänenmodell" umfassen), das eine Abhängigkeit des zu testenden Systems darstellt.
In diesen Situationen habe ich die Philosophie, die gegeben istDas Domänenobjekt verfügt über eine eigene umfassende Abdeckung für Komponententests. Das Vertrauen, dass das Objekt wie in einem Komponententest für ein anderes SUT entworfen funktioniert, verstößt nicht unbedingt gegen den Komponententest. Wenn dieser Test aufgrund einer Änderung der Domäne unterbrochen würde, würde ich erwarten, dass auch der Komponententest des Domänenobjekts unterbrochen wird, was mich zu etwas führt, das untersucht werden muss. Wenn der Komponententest des Domänenobjekts ordnungsgemäß als roter Test aktualisiert und dann mit der Änderung grün gemacht wurde und dieser andere Test dann fehlgeschlagen ist, ist dies auch nicht unbedingt eine schlechte Sache. Dies bedeutet, dass die Erwartungen dieses anderen Tests im Widerspruch zu den neuen Erwartungen für die Domäne stehen, und ich muss sicherstellen, dass beide miteinander und mit den übergeordneten Akzeptanzkriterien des Systems übereinstimmen.
Als solches würde ich ein Domänenobjekt nur verspotten, wenn dieses Domänenobjekt "Nebenwirkungen" hervorrief, die aus Sicht der Komponententests unerwünscht waren (dh externe Ressourcen wie Datenspeicher berühren), oder wenn die Logik des Domänenobjekts ausreichend komplex wäre Das Versetzen in den richtigen Zustand für den Test wird zu einem Hindernis für die Definition und das Bestehen des Tests.
Das wird dann zur treibenden Frage; was ist einfacher Um das Domain-Objekt für den beabsichtigten Zweck innerhalb des Tests zu verwenden oder es zu verspotten? Tun Sie, was einfacher ist, bis es nicht mehr die einfachere Option ist, z. B. wenn eine Funktionsänderung den Test des Dienstes auf komplexe Weise durchbricht. Wenn dies passiert, schreiben Sie den Test neu, um ein Modell zu erstellen, das die vom Service abhängigen funktionalen Anforderungen aufdeckt, ohne die Komplexität, die ihn bricht.
In beiden Fällen sollte es einen Integrationstest geben, der das in den realen Dienst eingesteckte reale Domänenobjekt verwendet, das die Interaktion zwischen diesen beiden auf einer höheren Abstraktionsebene testet (z. B. zum Testen nicht nur der Funktionalität hinter einem Dienst Endpunkt, aber ein Proxy, über den das Domänenobjekt serialisiert und gesendet wird).
quelle
Wenn Sie der abhängigen Klasse vertrauen, dass sie ordnungsgemäß funktioniert, und hoffen, dass einige Komponententests fehlschlagen, wenn etwas dort nicht funktioniert, sollte dies sehr gut getestet werden . Vielleicht fehlen einige wichtige Unit-Tests? Es kann einen ungetesteten Fall geben, der einen Fehler erzeugt, der in meiner ursprünglichen Testklasse erzeugt wird und nicht in der abhängigen Klasse selbst abgefangen wird.
Meiner Meinung nach sollten abhängige Klassen für Unit-Tests verspottet werden. Wenn dies nicht der Fall ist, handelt es sich um einen Integrationstest.
quelle