2013-08-28 4 views
7

Ich habe versucht, eine Antwort zu finden, aber es scheint, dass es nicht viel diskutiert wird. Ich habe einen Kompositionsstamm meiner Anwendung, wo ich einen DI-Container erstelle und alles dort registriere und dann benötigte Klassen der obersten Ebene aufleite, die alle Abhängigkeiten bekommen. Da dies alles intern geschieht, wird es schwierig, den Kompositionswurzel zu testen. Sie können virtuelle Methoden, geschützte Felder und so weiter machen, aber ich bin kein großer Fan davon, solche Dinge einzuführen, nur um Unit-Tests durchführen zu können. Es gibt keine großen Probleme mit anderen Klassen, da sie alle die Konstruktorinjektion verwenden. Die Frage ist also - macht es viel Sinn, die Kompositionswurzel überhaupt zu testen? Es hat einige zusätzliche Logik, aber nicht viel und in den meisten Fällen würden irgendwelche Fehler dort während des Anwendungsstarts auftauchen. Einige Code, den ich habe:Benötigt der Kompositionswurzel Komponententests?

public void Initialize(/*Some configuration parameters here*/) 
    { 
     m_Container = new UnityContainer(); 

     /*Regestering dependencies*/ 

     m_Distributor = m_Container.Resolve<ISimpleFeedMessageDistributor>(); 
    } 

    public void Start() 
    { 
     if (m_Distributor == null) 
     { 
      throw new ApplicationException("Initialize should be called before start"); 
     } 

     m_Distributor.Start(); 
    } 

    public void Close() 
    { 
     if (m_Distributor != null) 
     { 
      m_Distributor.Close(); 
     } 
    } 
+0

Was möchten Sie hier genau testen? Composition root ist der Haken für die Anwendungsplattform. Sie werden keinen einfachen Weg finden, sich über den gesamten Infrastrukturcode lustig zu machen. –

+0

Nun, zum Beispiel wollte testen, dass die Konfiguration, die kommen, ordnungsgemäß analysiert werden, dass die Aufrufe m_Distributor.Start() und so weiter startet. Also ich bin mir nicht sicher, ob das viel benötigt wird ... –

+0

Verwenden Sie XML-Dateien zur Konfiguration? Kannst du alle Container-Konfigurationen in Installer (Installer sind in Castle Windsor, sie heißen Module in Ninject) Klassen? Ich habe nie Unity benutzt. –

Antwort

8

macht es viel Sinn machen, die Zusammensetzung Wurzel überhaupt zu testen?

Möchten Sie wissen, ob Ihre Anwendung korrekt geschrieben wurde? Sie tun wahrscheinlich, und deshalb schreiben Sie Tests. Aus diesem Grund sollten Sie Ihre Kompositionswurzel testen.

Diese Tests sind jedoch speziell auf die Korrektheit der Verdrahtung des Systems ausgerichtet. Sie möchten nicht testen, ob eine einzelne Klasse korrekt funktioniert, da dies bereits durch einen Komponententest abgedeckt ist. Sie möchten auch nicht testen, ob Klassen andere Klassen in der richtigen Reihenfolge aufrufen, weil Sie dies in Ihren normalen Integrationstests testen möchten (z. B. einen MVC-Controller aufrufen und sehen, ob der Aufruf in der Datenbank endet)).

Hier sind einige Dinge, die Sie wahrscheinlich testen sollten:

  • Dass alle Top-Level-Klassen aufgelöst werden kann. Dies verhindert, dass Sie durch alle Bildschirme in der Anwendung klicken müssen, um herauszufinden, ob alles richtig verdrahtet ist.
  • Diese Komponenten sind nur von gleichwertigen oder langlebigeren Diensten abhängig. Wenn Komponenten von einer anderen Komponente abhängen, die mit einer kürzeren Lebensdauer konfiguriert ist, "fördert" diese Komponente die Lebensdauer dieser Abhängigkeit, was häufig zu Fehlern führt, die schwer zu reproduzieren und zu beheben sind. Die Überprüfung dieser Art von Problemen ist wichtig. Dieser Fehlertyp wird auch als Lifestyle-Mismatch oder Captive-Abhängigkeit bezeichnet.
  • Diese Decorators und andere Interception-Mechanismen, die für die Richtigkeit der Anwendung entscheidend sind, werden korrekt angewendet. Decorators könnten beispielsweise übergreifende Aspekte wie Transaktionsverarbeitung, Sicherheit und Zwischenspeicherung hinzufügen und es ist wichtig, dass diese Probleme in der richtigen Reihenfolge ausgeführt werden (z. B. muss eine Sicherheitsüberprüfung durchgeführt werden, bevor der Cache abgefragt wird), aber es kann schwierig sein Testen Sie dies mit einem normalen Integrationstest.

Um dies tun zu können, benötigen Sie jedoch eine verifiable DI configuration. Bitte beachten Sie, dass not everybody diese Meinung teilt. Meine Erfahrung ist jedoch, dass die Überprüfung der Richtigkeit Ihrer Konfiguration sehr wertvoll ist.

So testen können diese Dinge mit einigen IoC-Containern herausfordernd sein, während andere IoC-Container Einrichtungen haben, um Ihnen dabei zu helfen (aber Unity leider die meisten dieser Funktionen fehlt).

Einige Container verfügen sogar über eine Art Verifikationsmethode, die aufgerufen werden kann, um die Konfiguration zu überprüfen. Was "verifizieren" bedeutet, unterscheidet sich für jede Bibliothek.Simple Injector zum Beispiel (Ich bin der Lead-Entwickler für Simple Injector) hat eine Verify Methode, die einfach alle Registrierungen iteriert und GetInstance auf jedem von ihnen aufruft, um sicherzustellen, dass jede Instanz erstellt werden kann. Ich rate Benutzern, die Sie anrufen, immer Verify in ihrem Kompositionswurzel wann immer möglich. Dies ist zum Beispiel nicht immer möglich, da ein Aufruf von Verify dazu führen kann, dass die Anwendung zu langsam startet, wenn die Konfiguration groß wird. Aber es ist immer noch ein guter Ausgangspunkt und kann eine Menge Schmerzen beseitigen. Wenn es zu lange dauert, können Sie den Anruf immer zu einem automatisierten Test verschieben.

Und für den einfachen Injektor ist dies nur der Anfang. Simple Injector enthält Diagnostic Services, der den Container auf häufige Fehlkonfigurationen überprüft, wie z. B. den zuvor genannten "Lifestyle-Konflikt".

Also sollten Sie unbedingt testen wollen, aber ich bin mir nicht sicher, ob ich diese Tests "Komponententests" nennen soll, obwohl es mir gelingt, diese Tests isoliert durchzuführen (ohne eine Datenbank oder einen Webdienst zu treffen).

+0

Schön, dass jemand diese Meinung teilt. Ich habe festgestellt, dass im letzten Jahr oder so, seit ich in meinen .NET-Projekten anfing, tatsächlich TDD zu üben, die große Mehrheit aller Fehler, die immer noch auftreten, in meinen IoC-Setups sind, weil ich sie nicht gut testen konnte oder konnte. – TeaDrivenDev

+0

Ich würde CompositionRoot nicht für Container testen, die die Konfiguration nicht offen legen oder über Verifizierungsmethoden verfügen. Weil es so einfach ist, neue Dienste überall in der Anwendung zu integrieren und zu leicht zu vergessen, das zu testen. Daher gibt jede manuelle Überprüfung nur ein falsches Gefühl der Sicherheit. Andererseits würde ich keinen Container verwenden, der nicht sicherstellen kann, dass alles richtig verdrahtet ist. – jgauffin

+1

@jgauffin: Ich glaube nicht, dass ein Container Ihnen absolute Sicherheit geben kann. Ich stimme jedoch zu, dass einige Container es einfacher machen, schlechte Dinge zu tun. Die Registrierung von Diensten später während der Lebensdauer ist wirklich eine schlechte Sache, und deshalb unterstützen Autofac, Simple Injector und Griffin.Container das nicht. – Steven