[JAVA] Versuchen Sie es mit powermock-mockito2-2.0.2

Einführung

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 und Powermock

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/

Versuchen Sie es mit

Verwenden Sie Mockito

Verwenden Sie einen Stummel

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));
	}
}

Argument Matcher

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));
	}

Einflussbereich der Verspottung

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));

	}

So geben Sie unterschiedliche Ergebnisse mit demselben Argumentwert zurück

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);

So geben Sie eine Ausnahme mit einer verspotteten Methode aus

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());
		}
	}

Rückruf-Stub

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.

Erstellen Sie ein Modell mit einer Zeile

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));
	}

Teilweise verspottet mit Spy

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));

	}

Überprüfung mit Verify

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);
	}

Überprüfung der Anzahl der Hinrichtungen

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);
	}

Überprüfung der Ausführungsreihenfolge

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");
	}

Verspotten der endgültigen Methoden

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

image.png

	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));

	}

Verwenden Sie PowerMock

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 {
}

Private Methode verspotten

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));

	}

Verspotten der statischen Methode

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);
	}

Identitätswechsel der aktuellen Zeit

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()));
	}

Verspotten Sie die in der Methode erstellte Instanz

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"));

	}

Zusammenfassung

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

Versuchen Sie es mit powermock-mockito2-2.0.2
Versuchen Sie es mit libGDX
Versuchen Sie es mit Maven
Versuchen Sie es mit GraalVM
Versuchen Sie es mit jmockit 1.48
Versuchen Sie es mit SwiftLint
Versuchen Sie es mit Log4j 2.0
Versuchen Sie es mit dem Axon Framework
Versuchen Sie es mit der REST-API von JobScheduler
Versuchen Sie es mit der Methode java.lang.Math
Versuchen Sie es mit der WhiteBox von PowerMock
Versuchen Sie es mit Talend Teil 2
Versuchen Sie es mit Talend Teil 1
Versuchen Sie es mit der F # -Liste
Versuchen Sie es mit der Methode each_with_index
Versuchen Sie es mit Spring JDBC
Versuchen Sie es mit GloVe mit Deeplearning4j
Versuchen Sie, mit Java zu kratzen [Hinweis]
Versuchen Sie es mit Cocoa von Ruby
Versuchen Sie es mit IntelliJ IDEA, da Sie dies nur einmal tun müssen
Versuchen Sie es mit Spring Boot Security
[Rails] Versuchen Sie, Faradays Middleware zu verwenden
[Verarbeitung] Versuchen Sie es mit GT Force.
[Vollständige Programmierung] §2 Versuchen Sie es mit Ruby
Probieren Sie Redmine auf dem Mac Docker aus
Versuchen Sie es mit Redis mit Java (jar)
[Java] Versuchen Sie, mithilfe von Generika zu implementieren
Versuchen Sie es mit dem Nachrichtensystem Pulsar
Versuchen Sie es mit der IBM Java-Methodenverfolgung
Versuchen Sie es mit dem Java SDK von Hyperledger Iroha
[Java] Wo haben Sie versucht, Java zu verwenden?
Versuchen Sie es mit dem Java Framework Nablarch [Web Application]
Versuchen Sie, || anstelle des ternären Operators zu verwenden
Probieren Sie HiveRunner aus
Versuchen Sie, den Dienst auf Android Oreo zu verwenden
Versuchen Sie es mit der Stream-API in Java
Versuchen Sie es mit Mockito
Java lernen Versuchen Sie es mit einem Scanner oder einer Karte
Versuchen Sie es mit Selen
Versuchen Sie es mit der JSON-Format-API in Java
Versuchen Sie es mit DbUnit
Versuchen Sie es mit Spring Boot mit VS-Code
Versuchen Sie es mit Reladomos MT Loader (Multi-Threaded Matcher Loader).
Versuchen Sie es mit der REST-API von JobScheduler - Java RestClient-Implementierung -
Versuchen Sie es mit der Emotion API von Android
Versuchen Sie es mit der Wii-Fernbedienung in Java
Versuchen Sie es mit Lombok
Versuchen Sie es mit simple_form / edit sogar untergeordneten Modellen
Versuchen Sie, einen GraphQL-Server mit grahpql-java-tools (+ kotlin) zu implementieren.
Versuchen Sie, Firebase Cloud-Funktionen unter Android (Java) zu verwenden.
Versuchen Sie es mit der RestClient Test-Klasse der REST-API-Java von JobScheduler.