Frage

Angenommen, Sie eine Klasse Foo mit eigenem Mitglied des Typs Bar haben. Sie wollen nicht, Nutzer wissen, dass Foo-Implementierung eine Bar enthält und Sie nicht möchten, dass Benutzer in der Lage sein, ihre eigene Bar zu schaffen und es durch Foo Konstruktor übergeben, jede andere Methode oder einer Konfigurationsdatei.

Edit:. Bar ist auch problematisch, dass es greift auf Ressourcen außerhalb der Kontrolle der Testumgebung wie zum Beispiel eine spezielle Datenbank, Netzwerkverbindung oder einem anderen Prozess

Was tun Sie, wenn Sie auch an Unit-Test Foo in der Lage sein wollen? Ist Dependency Injection noch möglich? Bedeutet dies, dass Bar und Foo sind zu eng gekoppelt (obwohl die Abhängigkeit einer Art und Weise ist) und dass diese Situation ist nie akzeptabel zu sein in?

War es hilfreich?

Lösung

[Disclaimer: Ich arbeite bei Typemock ]

Sie haben drei Möglichkeiten:

  1. Erstellen Sie eine interne Methode, dass setzt die Bar-Klasse -. Mit InternalVisibleTo in den assemblyInf.cs Datei, die Sie Ihre Tests ermöglichen können, dass die Klasse festlegen
  2. Verwenden DI die Bar-Klasse, während des Test Wechsel zu injizieren, dass die Klasse mit einem Dummy oder Fälschung.
  3. Verwenden Sie Faking / Mockframework wie Typemock Trenner (.NET), die Sie Satz gefälschte Verhalten auf Objekte ermöglichen innerhalb einer anderen Klasse erstellt mit Isolate.Swap.NextInstance<Bar>.With(fakeBar);

Andere Tipps

Sie wollen nie zu verbergen Abhängigkeiten, wenn Sie ihm helfen können.

Wenn es Ihr Code ist, sollten Sie die Abhängigkeit machen explizit durch Bar Redesign der Objekte durch die teure Ressource erzeugt zu akzeptieren, anstatt Zugriff auf die teure Ressource direkt: den Datenbank-Zugriffscode bewegen (oder was auch immer es ist) aus Bar und in Foo, wo Sie auch Test verdoppelt injizieren.

Wenn das nicht praktisch ist (dh Sie ist der Umgang mit jemandem anderen Klassen), Drors Liste sehr gut ist.

Wenn die Art Bar ist nur eine Implementierung Detail von Foo, dann Unit-Tests nie über das Erstellen von Bars zu sorgen, da sie sowieso nur die öffentliche Schnittstelle von Foo ausüben sollen.

EDIT:. Wenn Bar externe Ressourcen zugreift, dann würde ich es eine explizite Abhängigkeit für Foo machen und benötigen dann eine Instanz in Foo-Konstruktor übergeben werden, die dann leicht für Unit-Tests verspottet werden könnten

Ihr Problem ist nicht, dass Sie ein privates Mitglied zugreifen müssen. Dass nur ein Symptom dafür ist, dass die Klasse in Frage nicht isoliert werden soll . Es kann immer nur eine sehr spezifische Verwendung, die ein Objekt new oben ist, die zu einer teueren Ressource geht.

Auch wenn Sie in Hacking um das untestable Design erfolgreich zu sein, werden Sie nur noch Tests durchführen Integration werden. Einheit Tests sind etwa Isolation, die das Gegenteil der Integration ist. Da diese Klasse kann nicht isoliert werden, durch Definition kann man nicht Unit-Test es.

Gibt es einen Grund, dass die Abhängigkeit unerwünscht ist Externalisierung? Was zu diesem Objekt befreit sie davon, dass abhängigkeits injiziert wie jede andere?

Bearbeiten :

Ich weiß, natürlich, dass Sie können isolieren es mit einigen Tricks. Doch diese Techniken Bypass öffentliche Schnittstellen, zukünftige Flexibilität zu begrenzen und die Wahrscheinlichkeit erhöht, dass jemand wird es brechen (im Grunde, zunichte gemacht, den Nutzen der privaten Mitglieder).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top