Ich habe zuvor Javas jmockit überprüft, aber es passt nicht ein wenig, daher ist es ein Memo, als ich Mockito und Powermock als Plan B überprüft habe.
Mockito https://site.mockito.org/
Mockito JavaDoc https://javadoc.io/doc/org.mockito/mockito-core/3.1.0/org/mockito/Mockito.html
Powermock https://github.com/powermock/powermock/
** Überprüfungsumgebung ** java version "1.8.0_202" Eclipse IDE for Enterprise Java Developers. Version: 2019-03 (4.11.0) Build id: 20190314-1200 JUnit4 mockito-2.23 powermock-mockito2-2.0.2
Mockito ist eine Bibliothek, die Mock zum Schreiben von Testcode bereitstellt. Als Einschränkung können Sie keine Konstruktoren, statischen oder privaten Methoden verspotten.
PowerMock erweitert sowohl EasyMock als auch Mockito um die Möglichkeit, statische, endgültige und sogar private Methoden zu verspotten. Es ist möglich, in Kombination mit Mockito zu arbeiten.
Dieses Mal habe ich "powermock-mockito2-junit-2.0.2.zip" aus dem Folgenden heruntergeladen und verwendet. https://github.com/powermock/powermock/wiki/Downloads
In dieser Umgebung ist zur Laufzeit ein Fehler aufgetreten, es sei denn, das folgende Jar wurde separat abgerufen und referenziert. ・ Byte-Buddy-1.9.10.jar ・ Byte-Buddy-Agent-1.9.10.jar https://howtodoinjava.com/mockito/plugin-mockmaker-error/
Das folgende Beispiel ist ein Beispiel für die Erstellung eines Stubs, der einen festen Wert zurückgibt, wenn ein bestimmtes Argument an die Mock-Methode übergeben wird.
package powermockTest;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class Test001 {
class ClassA {
public int testInt(int x, int y) {
return x + y;
}
}
@Test
public void testWhen1() {
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(5, 6)).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, mockedA.testInt(5, 6));
//Nicht verspottete Ergebnisse
assertEquals(0, mockedA.testInt(5, 7));
}
}
Die beim Verspotten angegebenen Parameter können sowohl Argument-Matcher als auch feste Werte verwenden. Im folgenden Beispiel können Sie anyInt () anstelle eines festen Werts verwenden, um eine beliebige Ganzzahl zu akzeptieren.
@Test
public void testWhen2() {
ClassA mockedA = mock(ClassA.class);
//Bedingungen können mit dem Argument Matcher angegeben werden.
//Weitere Argument-Matcher finden Sie weiter unten
// https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/ArgumentMatchers.html
when(mockedA.testInt(anyInt(), anyInt())).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, mockedA.testInt(5, 6));
assertEquals(99, mockedA.testInt(5, 7));
}
Sie können auch die folgenden Argumentvergleicher verwenden https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/ArgumentMatchers.html
Beachten Sie, dass Sie einen Argumentvergleich nicht nur für einige der Argumente einer Methode mit mehreren Argumenten verwenden können. Verwenden Sie den Argument-Matcher für alle Argumente. Wenn Sie einen Literalwert verwenden möchten, lautet die Implementierung wie folgt.
@Test
public void testWhen3() {
//Wenn Sie einen Argument-Matcher verwenden, müssen alle Argumente vom Matcher bereitgestellt werden.
/* eq(5)Wenn Sie 5 ohne Verwendung angeben, tritt der folgende Fehler auf.
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 1 recorded:
*/
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(eq(5), anyInt())).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, mockedA.testInt(5, 6));
assertEquals(99, mockedA.testInt(5, 7));
//Nicht verspottete Ergebnisse
assertEquals(0, mockedA.testInt(6, 7));
}
Wenn Sie in jmockit eine Klasse haben, die mit @Mocked verspottet wurde, werden alle Instanzen verspottet, die während dieses Testzeitraums erstellt wurden. mockito macht nicht folgendes:
@Test
public void testWhen4() {
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(5, 6)).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, mockedA.testInt(5, 6));
//Im Gegensatz zu jmockit wirkt sich dies nicht auf die nächste erstellte Instanz aus.
ClassA objA = new ClassA();
assertEquals(11, objA.testInt(5, 6));
}
Implementieren Sie Folgendes, um ein anderes Ergebnis mit demselben Argument zurückzugeben.
//So geben Sie unterschiedliche Ergebnisse mit denselben Argumenten zurück
@Test
public void testWhen5() {
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(5, 6))
.thenReturn(99)
.thenReturn(100);
//Ergebnis von mock angegeben
assertEquals(99, mockedA.testInt(5, 6));
assertEquals(100, mockedA.testInt(5, 6));
assertEquals(100, mockedA.testInt(5, 6));
//Eine andere Art zu schreiben
when(mockedA.testInt(1, 2)).thenReturn(10,20,30);
assertEquals(10, mockedA.testInt(1, 2));
assertEquals(20, mockedA.testInt(1, 2));
assertEquals(30, mockedA.testInt(1, 2));
assertEquals(30, mockedA.testInt(1, 2));
}
Wenn Sie Folgendes implementieren, wird es mit dem am Ende beschriebenen Inhalt überschrieben.
when(mockedA.testInt(5, 6)).thenReturn(99); //Dies wird ignoriert
when(mockedA.testInt(5, 6)).thenReturn(100);
Implementieren Sie Folgendes, um eine Ausnahme mit einer verspotteten Methode auszugeben.
@Test
public void testWhen6() {
ClassA mockedA = mock(ClassA.class);
doThrow(new IllegalArgumentException("test")).when(mockedA).testInt(5, 6);
try {
//Holen Sie sich den zweiten in Erwartungen festgelegten Wert
mockedA.testInt(5, 6);
fail();
} catch (IllegalArgumentException ex) {
assertEquals("test", ex.getMessage());
}
}
@Test
public void testWhen6_2() {
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(5, 6)).thenThrow(new IllegalArgumentException("test"));
try {
//Holen Sie sich den zweiten in Erwartungen festgelegten Wert
mockedA.testInt(5, 6);
fail();
} catch (IllegalArgumentException ex) {
assertEquals("test", ex.getMessage());
}
}
Stubs über die Antwortschnittstelle (https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/stubbing/Answer.html) sind zulässig.
@Test
public void testWhen7() {
ClassA mockedA = mock(ClassA.class);
when(mockedA.testInt(5, 6)).thenAnswer(
new Answer<Integer>() {
public Integer answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
System.out.println("getArguments----------------");
for (Object arg : args) {
System.out.println(arg);
}
//Verdoppeln Sie den Wert der realen Verarbeitung
return (int)invocation.callRealMethod() * 2;
}
}
);
//Ergebnis von mock angegeben
assertEquals(22, mockedA.testInt(5, 6));
}
InvocationOnMock ist für die Rückrufmethode verfügbar. Es ist möglich, die Argumente über InvocationOnMock, die verspottete Methode, zu übergeben und die eigentliche Methode auszuführen.
Mit der folgenden Implementierung ist es möglich, ein Modell mit einer Zeile zu erstellen.
@Test
public void testWhen8() {
ClassA mockedA = when(mock(ClassA.class).testInt(anyInt(), anyInt())).thenReturn(99).getMock();
assertEquals(99, mockedA.testInt(5, 6));
}
Mit Spy ist es möglich, nur einen Teil des Objekts zu verspotten. Das folgende Beispiel gibt nur dann einen verspotteten Wert zurück, wenn er mit bestimmten Argumenten ausgeführt wird. Ansonsten wird das Ausführungsergebnis der eigentlichen Methode zurückgegeben.
@Test
public void testSpy1() {
ClassA objA = new ClassA();
ClassA spyA = Mockito.spy(objA);
when(spyA.testInt(5, 6)).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, spyA.testInt(5, 6));
//Nicht verspottete Ergebnisse
//Die reale Sache heißt anders als die Zeit des Scheines.
assertEquals(12, spyA.testInt(6, 6));
}
Mit verify können Sie überprüfen, wie die verspottete Methode ausgeführt wurde.
@Test
public void testVerify1() {
ClassA mockedA = mock(ClassA.class);
mockedA.testInt(5,6);
mockedA.testInt(3,4);
//Stellen Sie sicher, dass die folgende Methode ausgeführt wird(Überprüfen Sie die Bestellung nicht)
verify(mockedA).testInt(3,4);
verify(mockedA).testInt(5,6);
}
times/ [never](https: // javadoc. io /static/org.mockito/mockito-core/3.1.0/org/mockito/Mockito.html#never--)/[atLeastOnce](https://javadoc.io/static/org.mockito/mockito-core /3.1.0/org/mockito/Mockito.html#atLeastOnce--)/[atMostOnce](https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/Mockito. html # atMostOnce-) / atLeast/[atMost] Es ist möglich zu überprüfen, wie oft es ausgeführt wurde (https://javadoc.io/static/org.mockito/mockito-core/3.1.0/org/mockito/Mockito.html#atMost-int-).
@Test
public void testVerify2() {
ClassA mockedA = mock(ClassA.class);
mockedA.testInt(5,6);
mockedA.testInt(3,4);
//2 mal testInt(?,?)Wird ausgeführt
verify(mockedA, times(2)).testInt(anyInt(),anyInt());
// testInt(1,1)Stellen Sie sicher, dass es nicht läuft
verify(mockedA, never()).testInt(1,1);
}
Mit [inOrder](https://javadoc.io/doc/org.mockito/mockito-core/3.1.0/org/mockito/Mockito.html#inOrder-java.lang.Object ...-) Es ist möglich, die Ausführungsreihenfolge von Methoden zu überprüfen.
class T1 {
void t1(String a) {
}
}
class T2 {
void t2(String a) {
}
}
@Test
public void testVerify3() {
T1 mocked = mock(T1.class);
mocked.t1("first");
mocked.t1("second");
//Überprüfen Sie die Bestellung
InOrder order = inOrder(mocked);
order.verify(mocked).t1("first");
order.verify(mocked).t1("second");
}
@Test
public void testVerify4() {
//Es ist auch möglich, die Ausführungsreihenfolge mehrerer Objekte zu überprüfen
T1 t1 = mock(T1.class);
T2 t2 = mock(T2.class);
t1.t1("call 1");
t2.t2("call 2");
t1.t1("call 3");
t2.t2("call 4");
//Überprüfen Sie die Bestellung
InOrder order = inOrder(t1, t2);
order.verify(t1).t1("call 1");
order.verify(t2).t2("call 2");
order.verify(t1).t1("call 3");
order.verify(t2).t2("call 4");
}
Die endgültige Methode kann mit den Standardeinstellungen nicht verspottet werden. Um das Verspotten der endgültigen Methode zu aktivieren, müssen Sie die folgende Datei erstellen.
/mockito-extensions/org.mockito.plugins.MockMaker
mock-maker-inline
class ClassB {
final public int testFinal(int x, int y) {
return x + y;
}
}
@Test
public void testFinal1() {
//endgültige Methoden können standardmäßig nicht verspottet werden
// /mockito-extensions/org.mockito.plugins.Erstellen Sie eine MockMaker-Datei und
//Sie müssen die folgenden Zeichen eingeben
// mock-maker-inline
ClassB mockedB = mock(ClassB.class);
when(mockedB.testFinal(5, 6)).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(99, mockedB.testFinal(5, 6));
}
Fügen Sie bei Verwendung von PowerMock der Klasse die folgende Anmerkung hinzu. ・ @RunWith (PowerMockRunner.class) ・ @PrepareForTest ({ZZZZ.class, XXX.class})
PrepareForTest sollte eine Klasse sein, die während des Tests auf Bytecode-Ebene bearbeitet werden muss. Beim Verspotten statischer Methoden, Konstruktoren und privater Methoden.
package powermockTest;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Calendar.class, java.lang.Math.class})
public class Test002 {
}
Im folgenden Beispiel wird die private Methode test1 verspottet und es wird bestätigt, dass der verspottete Wert zurückgegeben wird, wenn er über test2 ausgeführt wird.
class ClassPrivate {
private int test1(int x, int y) {
return x + y;
}
public int test2(int x) {
return test1(x, x) + 1;
}
}
@Test
public void testPrivate1() {
ClassPrivate objA = new ClassPrivate();
ClassPrivate spyA = PowerMockito.spy(objA);
PowerMockito.when(spyA.test1(5, 5)).thenReturn(99);
//Ergebnis von mock angegeben
assertEquals(100, spyA.test2(5));
assertEquals(99, spyA.test1(5,5));
}
Das folgende Beispiel ist ein verspottetes Beispiel für java.lang.Math.random.
//Ein Beispiel für zufällige Verspottung
@Test
public void testStatic1() {
//Bitte stellen Sie Folgendes in der Klasse ein
// @PrepareForTest({ java.lang.Math.class})
PowerMockito.mockStatic(java.lang.Math.class);
PowerMockito.when(java.lang.Math.random()).thenReturn(1.5);
assertEquals(1.5, java.lang.Math.random(), 0.1);
}
Wenn die statische Methode verspottet werden kann, kann die aktuelle Zeit als geeignete Zeit getarnt werden.
//Beispiel für das Verspotten der aktuellen Zeit
@Test
public void testStatic2() {
//Bitte stellen Sie Folgendes in der Klasse ein
// @PrepareForTest({ Calendar.class})
Calendar cal = Calendar.getInstance();
cal.set(2018, 1, 25, 23, 32, 30);
cal.set(Calendar.MILLISECOND, 0);
PowerMockito.mockStatic(Calendar.class);
PowerMockito.when(Calendar.getInstance()).thenReturn(cal);
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
assertEquals("20180225233230000", sdf.format(c.getTime()));
}
Verwenden Sie PowerMockito.whenNew, um die in der Methode erstellte Instanz zu verspotten.
class classA {
public String getA() {
return "getA";
}
}
class classB {
public String hoge(String x) {
return x + (new classA()).getA();
}
}
//Verspotten Sie die Instanz, um das in der zu testenden Methode verwendete Objekt zu verspotten
@Test
public void testInner() throws Exception {
classA mockedA = Mockito.mock(classA.class);
when(mockedA.getA()).thenReturn("abc");
PowerMockito.whenNew(classA.class).withNoArguments().thenReturn(mockedA);
classB obj = new classB();
assertEquals("testabc", obj.hoge("test"));
}
Ich denke, dass es viele Anwendungsfälle gibt und die niedrigen Lernkosten einen Vorteil gegenüber JMockit haben. Darüber hinaus scheint die in JMockit vorhandene Abdeckungsmessung nicht durchgeführt werden zu können.
Recommended Posts