Spritzen in private, package-oder öffentlichen Bereich oder einen setter?
Sehe ich viele Java-Beispiele für die Verwendung von dependency injection mit privaten Bereichen ohne öffentlichen setter wie diese:
public SomeClass {
@Inject
private SomeResource resource;
}
Aber das ist eine schlechte Idee, wenn die Injektion sollte manuell durchgeführt werden zum Beispiel in unit-tests.
Gibt es mehrere Möglichkeiten, um dieses Problem zu lösen:
- fügen Sie einen öffentlichen setter:
setSomeResource(SomeResource r)
- das Feld der öffentlichen
- das Feld Paket geschützt
Möchte ich vermeiden, setter, da ist nichts wirklich passiert, in es. Also ich würd lieber die öffentlichen oder das Paket geschützt. Was empfehlen Sie?
- stackoverflow.com/q/20270391/975169 automatische Injektion mit Mockito
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bevorzuge ich die setter
Aber das ist nur meine Meinung
Einen Weg, um zu vermeiden, erstellen eine setter für das Feld mit constructor injection. Dies erlaubt Ihnen sogar, zu erklären, das Feld als final.
Geht es so:
Hinzufügen setter ist keine optimale Lösung, da Sie das hinzufügen von Produktions code der nicht benötigt wird.
Eine alternative ist die Nutzung von Spring ReflectionTestUtils-Klasse zu injizieren Ihre test-Abhängigkeiten mithilfe von reflektion, siehe http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/test/util/ReflectionTestUtils.html
BEARBEITEN (2017): Jedoch ist die Reflexion eine noch schlechtere Lösung als das hinzufügen setter. Die Ursache für dieses Chaos ist die Tatsache, dass der Frühling macht es möglich, zu injizieren Werte ohne Set-Methoden oder Konstruktoren. Meine aktuelle Haltung ist, zu bleiben, um mit einer von den beiden, und vermeiden Sie die Verwendung von black magic-injection-Verfahren.
Empfehle ich die Verwendung von setter. In diese Frage sind die Vorteile der Verwendung von Getter und setter.
Mit Hilfe der Antwort auf meine (in Bezug auf diese) Frage:
Wie app-Server Spritzen in privaten Bereichen?
Codiert ich diesem einfachen Beispiel auf, wie zu injizieren, ohne setter.
Vielleicht hilft es
Run-Ausgang:
Mit Feld-basierte Injektion, Sie laufen in das Problem, das Sie beschreiben, mit dem testen. Auch mit Set-based injection, eine Instanz einer Klasse erstellt werden kann, die in einem unvollständigen Zustand bei der Ausführung von tests, wenn Sie vergessen, einige der Abhängigkeiten. Ich praktiziere seit constructor injection zuletzt aufgrund der Tatsache, dass es zwingt Sie, um alle Abhängigkeiten, wenn Sie erstellen eine Instanz einer Klasse während der Tests. Die Antwort oben von Andre Rodrigues erklärt, wie dies erreicht werden.
Mögliche Lösungen für dieses:
Verwendung eines CDI-bewusst-Test-Frameworks wie JGlue CDI-Einheit. Auf diese Weise müssen Sie keine setter. Sie definieren lediglich die Abhängigkeit innen Ihre tests in der Regel mit einem Mockito mock-Objekt. IMHO ist dies die beste Lösung, da Sie nicht verlangen, dass Sie nichts extra für die Prüfung.
Injizieren in Konstruktor oder setter. Das ist richtig, Sie können Spritzen in-setter! Mehr Informationen finden Sie hier.
Verwendung einer geschützten setter. Einfach und funktioniert in jedem Fall. Da ist es geschützt, Sie können greifen Sie von Ihrem test-Klasse (welche sollten das gleiche Paket definition getesteten Klasse), und keine anderen packages zugreifen kann.
Verwenden Sie eine get-und überschreiben Sie es bei der Prüfung. In der test-Klasse erstellen, erstellen Sie eine neue innere Klasse, die Sie erweitert die getestete Klasse und überschreiben Sie die get-Methode. Dies hat jedoch einen großen Nachteil: Ihre test-Klasse verwenden muss, um die getter-intern anstelle des Feldes. Viele potenziell verbuggt boilerplate...