Ich bevorzuge es, meine Handler frei von ASP.NET-Infrastruktur zu halten, die sehr schwer zu testen ist (ja, sogar in ASP.NET Core). Aber manchmal passiert es, und Sie haben eine Abhängigkeit wie UserManager (ich möchte eines Tages wissen, warum es keine Schnittstelle ist), HttpContext usw. und Komponententests werden in eine Spott-Hölle verwandelt.
Ich habe versucht, Integrationstests dafür zu verwenden, indem ich einen TestServer erstellte und die gesamte ASP.NET-Infrastruktur für jeden API-Aufruf initialisiert habe. Es funktioniert ganz gut, aber manchmal scheint es wie ein Overkill, wenn ich die einfache Logik meines Handlers testen möchte. Und während es das technische Problem der ASP.NET-Infragestellung löst, behebt es das Architekturproblem (wenn man es so betrachtet), ASP.NET-Infrastruktur in seinen Handlern zu haben.
Ich würde gerne wissen, was die empfohlenen Ansätze sind, um damit umzugehen?
Ich fühle deinen Schmerz. Ich bin über einen fantastischen Blob Post gestolpert von Jimmy Bogard, der dieses Problem behandelt, indem er das verwendet, was Martin Fowler Subkutane Tests nennt. Ich werde den Experten die tiefe Erklärung überlassen, aber in aller Kürze vermeiden subkutane Tests einfach alle schwierig zu testenden Aspekte der Benutzeroberfläche.
Schamloser Stecker: Ich schreibe gerade ein Wiki Diese Muster werden in einem Beispiel-End-to-End-Projekt auf GitHub demonstriert. Es ist nicht schwer zu folgen, aber es ist wahrscheinlich zu viel Code für eine SO-Antwort.
Um zusammenzufassen:
Zu lösen:
Das ist es im Grunde genommen. Jedes Mal, wenn Sie einen Integrationstest für einen Ihrer Handler ausführen:
Ich würde meiner Antwort weitere Codebeispiele hinzufügen, aber zwischen dem Blogpost und dem Wiki, das ich bereitgestellt habe, ist es viel einfacher, den Codebeispielen zu folgen.
Ich würde sagen, es hängt vom Grad des Selbstvertrauens ab, den Sie am Ende haben wollen. Wenn Sie sicherstellen möchten, dass das gesamte System wie erwartet funktioniert, dann sind Integrationstests mit TestServer
wahrscheinlich der richtige Weg.
Ein Vorteil von MediatR ist jedoch, dass Sie Ihre Geschäftslogik von der Anwendung, die sie verwendet, entkoppeln können. Aus diesem Grund gibt es auf der obersten Ebene, sagen wir in Controllern, keine Logik, sondern nur eine Delegation an den Mediator.
Damit haben Sie recht, dass Ihre Logik manchmal Informationen von der Hosting-Anwendung benötigt. Ein Beispiel wäre der Benutzer, der die Anfrage stellt, auf die im HTTP-Kontext zugegriffen werden kann.
Wenn Sie in diesem Fall vermeiden möchten, dass Sie einen Test-HTTP-Server zum Testen Ihrer Logikfunktionen einrichten müssen, können Sie diese Informationen in einer Abstraktion darstellen, und Ihr Handler würde dann eine Abhängigkeit von dieser Abstraktion übernehmen. Ihre Tests könnten dann diese Abhängigkeit verspotten, während Sie das reale System für alles andere verwenden.
Macht das Sinn?
Mediatr oder nein, Sie sollten immer versuchen, nur sehr grundlegende Logik in Ihren Controllern zu übergeben und Business Intelligence-Klassen von dort injizieren, um die eigentliche Arbeit zu tun. Wenn Sie ihnen Schnittstellen zu dieser Geschäftslogik hinzufügen, werden die Abhängigkeiten Ihrer Controller in Ihren Komponententests leicht verspottet und Ihre Tests können sich darauf konzentrieren, ob sie diese Schnittstellen richtig implementieren und nur die grundlegende Arbeit der Routing-Eingabe / Ausgabe ausführen. Und Ihre eigentliche Geschäftslogik kann noch einfacher getestet werden.
Für die Klassen, die statisch sind, zum Beispiel zum Lesen der web.config-Einstellungen, ist eine Strategie, die ich sehr mag, eine Wrapper-Klasse um sie herum. Während der ConfigurationManager statisch ist, kann ich immer noch eine reguläre Klasse mit einer Schnittstelle schreiben, der Methoden oder Eigenschaften hinzugefügt werden, um eine bestimmte Einstellung (vorzugsweise semantisch benannt) aus dem Konfigurationsmanager zu lesen. Jetzt kann ich jede konfigurierte Einstellung (oder Abwesenheit davon) in meinem Test leicht verspotten, indem ich nur die Schnittstelle verspotte und verschiedene Rückgabewerte einrichte.
Tags und Links asp.net-web-api asp.net asp.net-core mediatr