Verwenden von Anwendungsinformationen mit Komponententests?

8

Ich habe eine MVC-Webanwendung und verwende Simple Injector für DI. Fast mein gesamter Code wird von Komponententests abgedeckt. Jetzt, da ich einige Telemetrieaufrufe in einigen Controllern hinzugefügt habe, habe ich Probleme, die Abhängigkeiten einzurichten.

Die Telemetrieaufrufe dienen zum Senden von Messwerten an den von Microsoft Azure gehosteten Application Insights-Dienst. Die App läuft nicht in Azure, nur ein Server mit ISS. Das AI-Portal informiert Sie über alle Arten von Anwendungen, einschließlich benutzerdefinierter Ereignisse, die Sie mit der Telemetriebibliothek senden. Daher benötigt der Controller eine Instanz von Microsoft.ApplicationInsights.TelemetryClient, die keine Schnittstelle hat und eine versiegelte Klasse mit 2 Konstruktoren ist. Ich habe versucht, es so zu registrieren (der hybride Lebensstil hat nichts mit dieser Frage zu tun, ich habe sie nur der Vollständigkeit halber aufgenommen):

%Vor%

Das Problem besteht darin, dass SI, da der TelemetryClient über zwei Konstruktoren verfügt, sich beschwert und die Validierung nicht besteht. Ich habe einen Post gefunden, der zeigt, wie das Konstruktorauflösungsverhalten des Containers überschrieben werden kann, aber das scheint ziemlich kompliziert zu sein. Zuerst wollte ich sichern und diese Frage stellen:

Wenn ich den TelemetryClient nicht zu einer injizierten Abhängigkeit mache (nur eine Neue in der Klasse erstellen), wird diese Telemetrie bei jedem Durchlauf des Komponententests an Azure gesendet, wodurch viele falsche Daten entstehen? Oder ist Application Insights intelligent genug, um zu wissen, dass es in einem Komponententest ausgeführt wird und nicht die Daten sendet?

Irgendwelche "Einblicke" in dieses Problem würden sehr geschätzt werden!

Danke

    
Randy Gamage 19.11.2015, 22:17
quelle

2 Antworten

14
  

Microsoft.ApplicationInsights.TelemetryClient, das keine Schnittstelle hat und eine versiegelte Klasse mit 2 Konstruktoren ist.

Diese TelemetryClient ist ein Framework-Typ und Framework-Typen sollten nicht von Ihrem Container automatisch verkabelt werden .

  

Ich habe einen Beitrag gefunden, der zeigt, wie das Konstruktorauflösungsverhalten des Containers überschrieben wird, aber das scheint ziemlich kompliziert zu sein.

Ja, diese Komplexität ist absichtlich, weil wir Menschen davon abhalten wollen, Komponenten mit mehreren Konstruktoren zu erstellen, denn dies ist ein Anti-Muster .

Anstatt Auto-Wiring zu verwenden, können Sie, wie @qujck bereits sagte, einfach die folgende Registrierung vornehmen:

%Vor%
  

Oder ist Application Insights intelligent genug, um zu wissen, dass es in einem Komponententest ausgeführt wird und nicht die Daten sendet?

Sehr unwahrscheinlich. Wenn Sie die Klasse testen möchten, die von diesem TelemetryClient abhängt, sollten Sie stattdessen eine falsche Implementierung verwenden, um zu verhindern, dass Ihr Komponententest fragil oder langsam wird oder Ihre Insight-Daten verschmutzt. Aber selbst wenn das Testen keine Rolle spielt, sollten Sie nach dem Prinzip der Abhängigkeitsinversion von (1) Abstraktionen abhängig sein (2) durch Ihre eigene Anwendung definiert. Sie scheitern beide Punkte, wenn Sie TelemetryClient verwenden.

Stattdessen sollten Sie eine (oder sogar mehrere) Abstraktionen über die TelemetryClient definieren, die speziell auf Ihre Anwendung zugeschnitten sind . Versuchen Sie also nicht, die API TelemetryClient mit ihren möglichen 100 Methoden nachzuahmen, sondern definieren Sie nur Methoden auf der Schnittstelle, die Ihr Controller tatsächlich verwendet, und machen Sie sie so einfach wie möglich. Machen Sie den Code des Controllers einfacher - und Ihr Unit-Test einfacher.

Nachdem Sie eine gute Abstraktion definiert haben, können Sie eine Adapterimplementierung erstellen, die das TelemetryClient intern verwendet. Ich stelle fest, dass Sie diesen Adapter wie folgt registrieren:

%Vor%

Hier gehe ich davon aus, dass TelemetryClient Thread-sicher ist und als Singleton funktionieren kann. Andernfalls können Sie Folgendes tun:

%Vor%

Hier ist der Adapter immer noch ein Singleton, aber er ist mit einem Delegaten ausgestattet, der die Erstellung von TelemetryClient ermöglicht. Eine andere Möglichkeit besteht darin, den Adapter das TelemetryClient intern erstellen (und vielleicht entsorgen) zu lassen. Das würde vielleicht die Registrierung noch einfacher machen:

%Vor%     
Steven 20.11.2015, 06:31
quelle
2

Wenn Sie nicht in den Abstraktions- / Wrapper-Pfad gehen wollen. In Ihren Tests könnten Sie den AppInsights-Endpunkt einfach an einen simulierten Lightweight-HTTP-Server verweisen (was in ASP.NET Core trivial ist).

appInsightsSettings.json

%Vor%

So richten Sie "TestServer" in ASP.NET Core ein Ссылка

    
DalSoft 30.03.2017 17:50
quelle