Wie kann ich Zugriff auf Klassenelemente, die in Java?
Ich habe Daten-Modell-Klassen enthalten, die private Felder, die soll nur gelesen werden (über eine get-Funktion). Diese Felder werden durch meine JPA-Persistenz-provider (eclipselink) während des normalen Betriebs, der Nutzung der Inhalte der Datenbank. Für unit-tests, die ich will, um Sie auf gefälschte Werte aus einer Nachbildung der Persistenz-Schicht. Wie kann ich das tun? Wie funktioniert eclipselink diese Werte gesetzt, eh?
Vereinfachtes Beispiel:
@Entity
class MyEntity
{
@Id
private Integer _ix;
public Integer ixGet()
{
return this._ix;
}
}
InformationsquelleAutor Hanno Fietz | 2009-08-20
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie nur Verspotten die Entität selbst, die Bereitstellung Ihrer eigenen implemenations der Getter?
Könnte man erstellen Sie eine anonyme Erweiterung in der mock-Persistenz-Schicht:
es gibt Probleme mit tun dies aber nicht - es geht um die Nebenwirkungen
Bitte erläutern Sie. Ich habe diese Technik ganz ausführlich beim testen einige eclipse-plugins, die ich schrieb. Spürte keine Nebenwirkungen, andere als einen warmen Schein des Glücks.
InformationsquelleAutor djna
Müssen Sie die Verwendung der Reflection-API. Verwenden Sie Klasse.getField (), um das Feld, dann rufen Sie setAccessable(true) auf dem Feld, so dass Sie können es schreiben, auch wenn es privat ist, und schließlich können Sie sich telefonisch set() schreibt einen neuen Wert ein.
Beispiel:
Sie möchten, setzen Sie das Feld "i", zu 3, auch wenn es privat ist:
Gibt es eine Reihe von Ausnahmen, die Sie behandeln muss.
Ich denke, das ist es was die Persistenz-provider verwendet, richtig?
In der Regel Persistenz-Provider nicht zwingen, Ihren Weg um die Berechtigungen. Sie werden entweder wählen Sie einen beschreibbaren "Feld", oder Sie schauen, um ein 'setField' Methode ist aufrufbar.
Naja, Sie scheinen in der Lage zu handhaben, meine Einheiten mit alle db-Felder auf "privat" gesetzt, nicht alle von Ihnen haben setter und setter, die es gibt, halten sich nicht an die beans-Konventionen (es ist immer vSetField statt setField Einklang mit dem ganzen rest von meinem code). Ich bin jetzt Fragen, wenn ich ' m setzen eine Leistungseinbuße auf meine Hartnäckigkeit durch spielen nicht nach den Regeln.
InformationsquelleAutor Jonathan
Können Sie eine test-Bibliothek wie Mockito, um Zugriff auf Objekte den internen Zustand im lese-und Schreibmodus. Zum Beispiel mit Mockito verwenden:
InformationsquelleAutor frhack
Können Sie ein mocking-framework wie powermock, um durch pass-Kapselung. In powermock, die Sie verwenden würden
Whitebox.setInternalState(..)
um einen privaten member.Eine weniger invasive Methode wäre, zu verhöhnen, ist die get-Methode. Ob das umsetzbar ist, würde davon abhängen, was sonst, hängt vom internen Zustand, aber wenn es genug ist, ist es die sauberere Lösung.
InformationsquelleAutor VoidPointer
Einige Methoden, die ich in der Vergangenheit verwendet habe:
InformationsquelleAutor Nils-Petter Nilsen
Weitere option, wenn Sie wirklich hassen, um Dinge zu machen, öffentlichkeit zu schaffen, ist eine Unterklasse zum testen, und bieten öffentlichen Zugang gibt.
Haben Sie ein paar Optionen:
Für eine Reihe von nützlichen Techniken, haben Sie einen Blick auf Michael Feder ' s Buch, Working Effectively With Legacy Code
InformationsquelleAutor Nader Shirazie
Können Sie hinzufügen Konstruktor mit parameter für das nur-lese-variable. Vergessen Sie nicht, fügen Sie einen Standardwert (null, parameter) Konstruktor.
InformationsquelleAutor Vincnetas
Konstruktor ist eine beste Weg, denke ich. Wenn diese Person hat wirklich readonly (nicht erlaubt, neue Instanzen zu erstellen in der Produktion-code) Sie können den Konstruktor mit package-Zugriff und verwenden Sie es nur innerhalb des tests. Und gibt es eine Möglichkeit, auch wenn Sie Ihre Standard-Konstruktor private oder package-access, Ihrer Persistenz-provider immer noch in der Lage, mit dieser Person, aber nicht sicher, ob - check mit eclipselink docs.
InformationsquelleAutor alsor.net