Mocking private-Methoden in der öffentlichen Methode mit PowerMock, Mockito, TestNG
Ich möchte schreiben Sie einen unit test für eine Klasse, die ich habe. Hat diese Klasse eine öffentliche Methode, und innerhalb der öffentlichen Methode Aufrufe von privaten Methoden in der gleichen Klasse. Ich möchte zu verspotten, die Aufrufe an diese privaten Methoden. Die Klasse ist ähnlich wie diese:
public class SomeClass {
public int somePublicMethod(int num) {
int num2 = somePrivateMethod1(num);
int num3 = somePrivateMethod2(num);
return num2 + num3;
}
private int somePrivateMethod1(int num) {
return 2*num;
}
private int somePrivateMethod2(int num) {
return 3*num;
}
}
Für meine unit-test-ich bin versucht, PowerMock mit Mockito und TestNG. Hier ist mein Versuch, ein test, der tests somePublicMethod:
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.spy;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.Assert;
import org.testng.annotations.Test;
@PrepareForTest(SomeClass.class)
public class SomeClassTest {
@Test
public void testSomePublicMethod() throws Exception {
int num = 4;
SomeClass someClassSpy = spy(new SomeClass());
doReturn(8).when(someClassSpy, "somePrivateMethod1", num);
doReturn(12).when(someClassSpy, "somePrivateMethod2", num);
int result = someClassSpy.somePublicMethod(num);
Assert.assertEquals(result, 20);
}
}
Wenn ich diesen test ausführen, bekomme ich eine Ausnahme und einige Hinweise:
FAILED: testSomePublicMethod
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.internal.PowerMockitoCore.doAnswer(PowerMockitoCore.java:31)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
Ist, habe ich mich auf einige Beispiele online, aber ich habe nicht gefunden eine mit PowerMock mit Mockito und TestNG speziell zu tun, was ich will. Kann mir jemand ein paar Tipps, was ich anders machen kann?
InformationsquelleAutor Thomas | 2012-05-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube nicht, dass dies ein problem mit PowerMock. Es sieht aus wie es sollte gut funktionieren. Ich Frage mich, ob es ein problem mit TestNG Interaktion mit PowerMock?
Habe ich keine Erfahrung mit TestNG, also ich habe versucht mit der Klasse in JUnit.
SomeClass
gelassen wurde, wie es ist,SomeClassTest
wurde minimal geändert, um die Verwendung von JUnit:Den test bestanden.
Tun, müssen Sie einen
PowerMockRunner.class
mit@RunWIth
oder eine ähnliche Anmerkung, wie mit JUnit? Wenn ich entfernen Sie Sie, dass Anmerkungen, die ich erhalten die gleiche Fehlermeldung, die du gepostet.EDIT:
Laut diesem link:
http://code.google.com/p/powermock/wiki/TestNG_usage
Müssen Sie sagen, TestNG zu verwenden, der PowerMock-Objekt-Fabrik. Um dies programmatisch tun, fügen Sie eine Methode wie Sie diese zu Ihrem test-Klasse:
oder sind Sie auf der sicheren Seite, Sie können auch erweitern, von der PowerMockTestCase:
InformationsquelleAutor Tom Tresansky
Können Sie nicht tun. Haben Sie versucht, mithilfe von reflektion?
Mithilfe von Reflexion, können Sie verhöhnen die privaten Methoden von spottenden die Methoden aufgerufen werden, oder einfacher: Sie können es ändern, um öffentliche temporäre, dann nach dem test (vielleicht in der tearDown) - Sie können es ändern, zurück zu private.
Hoffe, dass dies helfen.
obwohl, den könnten wir nachdenken, aber es wird nicht empfohlen. Wie Sie wissen, die private Methode sollte aufgerufen werden, indem Sie eine Ihrer öffentlichen Methoden sowieso, so ist es besser, alles zu testen, von der öffentlichen Methode.
Bei der Implementierung von etwas, so stellen Sie sicher, Sie schreiben einen testbaren code. Sie können versuchen, die Suche auf google für "Prüfbar vs Untestable code" finden Sie einige bewährte Methoden zu tun und einige Fehler zu verhindern.
Ja die private Methode aufgerufen wird von der öffentlichen Methode, aber das problem ist private Methode wird immer die Ausnahme in der test Umgebung, wie es die Methode, um DB-Verbindung.
Isolation ist das wichtigste in unit-Tests, die Sie benötigen, zu isolieren, es von anderen Dingen, wie andere Dienste, andere Klassen... natürlich, zu isolieren, es von der Umgebung (Datenbank)
InformationsquelleAutor nnhthuan
Ich denke, Sie sind hiting eine Mockito Grenze hier. In ähnlichen Fällen, die ich verwenden Powermock-Methode Ersatz oder deklarieren Sie die Ziel-Methode als protected und überschreiben Sie es bei der Konstruktion der getesteten Instanz der Klasse.
Hoffe, das hilft.
InformationsquelleAutor