6

Ich verwende das Simple Injector Dependency Injection-Framework und es sieht cool und nett aus. Aber nachdem ich eine Konfiguration erstellt und verwendet habe, möchte ich jetzt wissen, wie ich von einer Konfiguration zu einer anderen wechseln kann.Verwenden Sie verschiedene Konfigurationen mit Simple Injector

Szenario: Stellen wir uns vor, ich habe eine Konfiguration in der Global Asax eingerichtet und ich habe die öffentliche und globale Container Instanz dort. Jetzt möchte ich einige Tests durchführen und möchte, dass sie Scheinklassen verwenden, also möchte ich die Konfiguration ändern.

Ich kann natürlich eine andere Konfiguration erstellen und sie der globalen Container standardmäßig erstellt, so dass jedes Mal, wenn ich einen Test ausführen die alternative Konfiguration festgelegt wird. Aber wenn ich das mache und obwohl ich im Entwicklungskontext bin, wird die Container für jeden geändert, sogar für normale Anfragen. Ich weiß, dass ich in diesem Zusammenhang teste, und das sollte nicht wichtig sein, aber ich habe das Gefühl, dass dies nicht der richtige Weg ist ... und ich frage mich, wie ich von einer Konfiguration zur anderen in der richtigen Weise wechseln kann.

+0

Sprechen Sie über die Einrichtung automatisierter Tests?Wenn dies der Fall ist, erstellen Sie den Container (mit Mocks, falls erforderlich) vor jedem Testfall neu. Dies ist '[TestInitialize]' in MSTest und '[SetUp]' in NUnit. –

Antwort

6

Wenn Sie Komponententests durchführen, sollten Sie den Container überhaupt nicht verwenden. Erstellen Sie einfach die zu testende Klasse, indem Sie ihren Konstruktor aufrufen und ihn mit den richtigen Mock-Objekten versorgen.

Ein Muster, das mir in der Vergangenheit sehr geholfen hat, ist die Verwendung einer einfachen Testklassen-spezifischen Fabrikmethode. Diese Methode zentralisiert die Erstellung der zu testenden Klasse und minimiert die Anzahl der Änderungen, die durchgeführt werden müssen, wenn sich die Abhängigkeiten der getesteten Klasse ändern. Dies ist, wie eine solche Fabrik Methode aussehen könnte: Tests

private ClassUnderTest CreateValidClassUnderTest(params object[] dependencies) 
{ 
    return new ClassUnderTest(
     dependencies.OfType<ILogger>().SingleOrDefault() ?? new FakeLogger(), 
     dependencies.OfType<IMailSender>().SingleOrDefault() ?? new FakeMailer(), 
     dependencies.OfType<IEventPublisher>().SingleOrDefault() ?? new FakePublisher()); 
} 

Für die Integration ist es viel häufiger den Behälter zu verwenden, und ein paar Abhängigkeiten des Behälters tauschen. Diese Integrationstests verwenden jedoch nicht den Container, den Sie in Ihrem Anwendungsstart erstellt haben, aber jeder Integrationstest wird in diesem Fall höchstwahrscheinlich eine eigene neue Containerinstanz haben, da jeder Test isoliert ausgeführt werden sollte. Und selbst wenn Sie einen einzigen Container von application_start verwendet haben, werden Ihre Integrationstests von einem separaten Projekt ausgeführt und beeinträchtigen nicht Ihre laufende Anwendung.

Obwohl jeder Integrationstest eine eigene Containerinstanz (falls vorhanden) erhalten sollte, möchten Sie dennoch so viel Containerkonfigurationscode wie möglich wiederverwenden. Dies kann erreicht werden, indem dieser Code in eine Methode extrahiert wird, die entweder eine neu konfigurierte Containerinstanz zurückgibt, wenn sie aufgerufen wird, oder eine bereitgestellte Containerinstanz konfiguriert (und nichts zurückgibt). Diese Methode sollte normalerweise eine unvollständige Konfiguration durchführen und der Aufrufer (entweder Ihre Tests oder globale Asax) sollten die fehlenden Konfigurationen hinzufügen.

Extrahieren dieses Codes: Sie können mehrere Endanwendungen verwenden, die sich zum Teil dieselbe Konfiguration teilen. ermöglicht Ihnen, den Container in einem Integrationstest zu überprüfen; und ermöglicht es Ihnen, Dienste hinzuzufügen, die von Ihren Integrationstests gespottet werden müssen.

Um das Leben einfacher zu machen, Simple Injector können Sie bestehende Registrierungen durch neue ersetzen (zum Beispiel eine verspottete). Sie können dies wie folgt aktivieren:

container.Options.AllowOverridingRegistrstions = true; 

Aber seien Sie vorsichtig damit! Diese Option kann die Tatsache verbergen, dass Sie versehentlich eine Registrierung überschreiben. Nach meiner Erfahrung ist es in den meisten Fällen viel besser, einen unvollständigen Container aufzubauen und die fehlenden Registrierungen nachträglich hinzuzufügen, anstatt sie zu überschreiben. Oder, wenn Sie sich dafür entscheiden, die Funktion außer Kraft zu setzen, aktivieren Sie die Funktion zum letzten möglichen Zeitpunkt, um versehentliche Fehlkonfigurationen zu verhindern.

+0

Danke. Es scheint so zu sein, was ich mir vorgestellt habe. –

Verwandte Themen