Wie kann ich eine Feldvariable verspotten, die inline initialisiert wird?
class Test {
private Person person = new Person();
...
public void testMethod() {
person.someMethod();
...
}
}
Hier möchte ich verspotten, person.someMethod()
während ich die Test.testMethod()
Methode teste , für die ich die Initialisierung einer person
Variablen verspotten muss . Irgendeine Ahnung?
Bearbeiten: Ich darf die Personenklasse nicht ändern.
java
mockito
junit4
powermockito
Arun
quelle
quelle
Person
. Zu den Optionen gehören das Hinzufügen eines Konstruktors oder eine Setter-Methode.Antworten:
Mockito wird mit einer Helferklasse geliefert, um Ihnen den Code der Reflexionskesselplatte zu ersparen:
Update: Leider hat das Mockito-Team beschlossen , die Klasse in Mockito 2 zu entfernen. Sie können also wieder Ihren eigenen Reflection-Boilerplate-Code schreiben, eine andere Bibliothek (z. B. Apache Commons Lang ) verwenden oder einfach die Whitebox- Klasse stehlen (sie ist MIT-lizenziert ).
Update 2: JUnit 5 enthält eigene ReflectionSupport- und AnnotationSupport- Klassen, die möglicherweise nützlich sind und Sie vor dem Abrufen einer weiteren Bibliothek bewahren.
quelle
internal
Paket enthalten und scheint unter Mockito 2.6.2 nicht mehr zu funktionieren.Ziemlich spät zur Party, aber ich wurde hier geschlagen und bekam Hilfe von einem Freund. Die Sache war, PowerMock nicht zu benutzen. Dies funktioniert mit der neuesten Version von Mockito.
Mockito kommt damit
org.mockito.internal.util.reflection.FieldSetter
.Grundsätzlich hilft es Ihnen, private Felder mithilfe von Reflektion zu ändern.
So verwenden Sie es:
Auf diese Weise können Sie ein Scheinobjekt übergeben und später überprüfen.
Hier ist die Referenz.
quelle
FieldSetter
ist in Mockito 2.x nicht mehr verfügbar.Class#getDeclaredField
akzeptiert einzelne Parameter, also müssen die Eltern so aussehenFieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person"), mockedPerson);
. So habe ich es falsch verstanden und dachte, es wäre eine gute Idee, es in Ihrem Beispiel zu beheben. Danke für Ihre Antwort.Wenn Sie Spring Test verwenden, versuchen Sie es mit org.springframework.test.util.ReflectionTestUtils
quelle
testImplementation("org.springframework:spring-test:5.1.2.RELEASE")
Ich habe bereits die Lösung für dieses Problem gefunden, die ich hier vergessen habe zu posten.
Wichtige Punkte für diese Lösung sind:
Ausführen meiner Testfälle mit PowerMockRunner:
@RunWith(PowerMockRunner.class)
Weisen Sie Powermock an, sich
Test.class
auf die Manipulation privater Felder vorzubereiten :@PrepareForTest({ Test.class })
Und schließlich verspotten Sie den Konstruktor für die Personenklasse:
PowerMockito.mockStatic(Person.class);
PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
quelle
mockStatic
Funktion, aber das ist in Ihrem Codebeispiel nicht dargestellt. Sollte das Codebeispiel denmockStatic
Aufruf haben oder ist dies für Konstruktoren nicht erforderlich?Der folgende Code kann verwendet werden, um den Mapper im REST-Client-Mock zu initialisieren. Das
mapper
Feld ist privat und muss während der Einrichtung des Komponententests festgelegt werden.quelle
Mit der Anleitung von @ Jarda können Sie dies definieren, wenn Sie für alle Tests den gleichen Wert für die Variable festlegen müssen:
Beachten Sie jedoch, dass die Einstellung privater Werte unterschiedlich sein sollte. Wenn sie privat sind, sind aus irgendeinem Grund.
Beispiel, ich benutze es zum Beispiel, um die Wartezeit eines Schlafes in den Unit-Tests zu ändern. In realen Beispielen möchte ich 10 Sekunden schlafen, aber im Unit-Test bin ich zufrieden, wenn es sofort ist. In Integrationstests sollten Sie den tatsächlichen Wert testen.
quelle