[JAVA] Essayez d'utiliser jmockit 1.48

Objectif

Le but de cet article est une note de mes recherches sur jmockit 1.48.

document http://jmockit.github.io/index.html

Code source https://github.com/jmockit/jmockit1

JavaDoc https://repo1.maven.org/maven2/org/jmockit/jmockit/1.48/jmockit-1.48-javadoc.jar

** Environnement de vérification ** java version "1.8.0_202" Eclipse IDE for Enterprise Java Developers. Version: 2019-03 (4.11.0) Build id: 20190314-1200 JUnit4

Qu'est-ce que jmockit

Lors de l'exécution de tests unitaires à l'aide de xUnit, les pièces dépendantes peuvent être un problème et difficiles à tester. image.png

Par exemple, dans les cas suivants. -Lorsqu'il est difficile de renvoyer un contenu arbitraire à la cible de test en raison de pièces dépendantes

Dans ces cas, vous pouvez faciliter les tests unitaires en utilisant la méthode créée par jmockit au lieu des parties dépendantes.

image.png

En utilisant jmockit, il est possible de transmettre une valeur pratique pour le test à la cible de test au lieu de la partie dépendante, et d'enregistrer et de vérifier comment la partie dépendante a été appelée à partir de la cible de test. Je vais.

Facile à utiliser

(1) Téléchargez Jar à partir de ce qui suit et faites-y référence à partir du projet. https://mvnrepository.com/artifact/org.jmockit/jmockit

Ou pour Maven, ajoutez ce qui suit à pom.xml

<!-- https://mvnrepository.com/artifact/org.jmockit/jmockit -->
<dependency>
    <groupId>org.jmockit</groupId>
    <artifactId>jmockit</artifactId>
    <version>1.48</version>
    <scope>test</scope>
</dependency>

(2) Ajouter un cas de test JUnit

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import mockit.Mock;
import mockit.MockUp;

public class SimpleTest {

	@Test
	public void test() {
        new MockUp<java.lang.Math>() {
        	@Mock
        	public double random() {
        		//Toujours 2.Renvoie aléatoire 5()Méthode
        		return 2.5;
        	}
        };
		assertEquals(2.5, Math.random(), 0.1);
		assertEquals(2.5, Math.random(), 0.1);
	}

}

(3) Dans la configuration d'exécution au moment de l'exécution de junit, ajoutez "-javaagent: jmockit-1.48.jar" à l'argument VM et exécutez. image.png

image.png

Voir ci-dessous pour plus de détails sur la façon de procéder: http://jmockit.github.io/tutorial/Introduction.html#runningTests

dépanner

Si initializationError se produit

** Un événement ** image.png

** Trace d'erreur **

java.lang.Exception: Method testVerifications should have no parameters
	at org.junit.runners.model.FrameworkMethod.validatePublicVoidNoArg(FrameworkMethod.java:76)
	at org.junit.runners.ParentRunner.validatePublicVoidNoArgMethods(ParentRunner.java:155)
//Abréviation
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

** Cause ** "-Javaagent: jmockit-1.48.jar" n'est pas ajouté à l'argument VM.

L'ordre des chemins de classes est-il important? Ou dois-je utiliser RunWith?

Parfois, il y a une déclaration selon laquelle il est important de faire le chemin de classe de construction dans l'ordre jmockit → junit. https://stackoverflow.com/questions/32817982/jmockit-wasnt-properly-initialized?rq=1

Ce n'est probablement pas un problème dans la version actuelle, ou c'est parce que "-javaagent: jmockit-X.XX.jar" n'est pas ajouté à l'argument VM.

En outre, il semble y avoir un moyen d'utiliser "@ RunWith (JMockit.class)" comme une autre solution à l'ordre du chemin de la classe de construction, mais au moins à partir de 1.48, cet attribut n'existe pas.

https://github.com/jmockit/jmockit1/issues/554

Comment utiliser jmockit

Mocking La simulation fournit un mécanisme pour séparer la classe testée de (une partie de) ses dépendances. Utilisez les annotations @ Mocked / @ Injectable / @ Capturing pour créer une instance simulée. Les instances simulées peuvent être définies sur le comportement attendu dans Expectations (#expectations) et peuvent être vérifiées dans Verifications (#verifications) comment l'instance simulée a été exécutée.

Annotation @mocked

Il est possible de se moquer en utilisant l'annotation @Mocked comme paramètre d'une méthode de cas de test ou un champ d'une classe de cas de test. Si vous utilisez l'annotation @Mocked, toutes les instances du même type seront simulées pendant la durée du test qui l'utilise.

Tout type peut être simulé à l'exception du type primitif et du type de tableau.

Voyons maintenant comment utiliser la classe suivante comme objet simulé.

** Cible de test **

package SampleProject;

public class Hoge001 {
	public int hoge(int x, int y) {
		return x + y;
	}
	public String hoge(String x) {
		return "test" + x;
	}
}

** Exemple d'utilisation de Mocked **

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge001;
import mockit.Expectations;
import mockit.Mocked;

public class Test001 {
	//Lorsque vous n'utilisez pas de maquette...
	@Test
	public void test0() {
		Hoge001 hoge = new Hoge001();
		assertEquals(11, hoge.hoge(5,6));
		assertEquals("testxxx", hoge.hoge("xxx"));
	}

	//Vous pouvez créer une instance simulée en la spécifiant comme paramètre de la méthode de test
	@Test
	public void test1(@Mocked Hoge001 mock) {
		new Expectations() {{
			//hoge est x=5, y =S'il est appelé par 6, renvoie 99 la première fois
			mock.hoge(5,6);
			result  = 99;
		}};
		//Si vous spécifiez un résultat de méthode dans les attentes, cette valeur est récupérée
		assertEquals(99, mock.hoge(5,6));
		//Valeur par défaut si les attentes ne spécifient pas de résultat de méthode(null)Devient
		assertEquals(null, mock.hoge("xxx"));

		// @Si vous utilisez Mocked, toutes les instances applicables seront simulées pendant la durée du test.
		Hoge001 hoge = new Hoge001();
		assertEquals(99, hoge.hoge(5,6));
		assertEquals(null, hoge.hoge("xxx"));

	}
}

test0 () est un cas de test lorsqu'il n'est pas simulé, et test1 () est un cas de test utilisant @Mocked comme paramètre. Pendant le scénario de test de test1 (), toutes les instances Hoge001 sont des instances simulées.

Confirmez qu'il s'agira d'un simulacre même s'il n'est pas créé directement dans le cas de test

Le test suivant confirme qu'il sera simulé même si vous n'avez pas créé l'instance directement dans le scénario de test.

** Cible de test ** La cible du test est Hoge002, qui est utilisée en créant une instance de Hoge001.

package SampleProject;

public class Hoge002 {
	public int test(int x , int y) {
		Hoge001 hoge1 = new Hoge001();
		return hoge1.hoge(x*2, y*2);
	}
}

** Code de test **

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge001;
import SampleProject.Hoge002;
import mockit.Expectations;
import mockit.Mocked;

public class Test001_3 {

	//Vous pouvez créer une instance simulée en la spécifiant comme paramètre de la méthode de test
	@Test
	public void test1(@Mocked Hoge001 mock) {
		new Expectations() {{
			//hoge est x=10, y =S'il est appelé par 12, la première fois renvoie 99
			mock.hoge(10,12);
			result  = 99;
		}};
		Hoge002 hoge2 = new Hoge002();
		assertEquals(99, hoge2.test(5,6));
	}
}

Si vous exécutez ce cas de test, vous pouvez voir que le Hoge001 créé par Hoge002 est une version simulée.

Cas utilisant @Mocked pour le champ de classe

Si vous utilisez @Mocked pour un champ de classe, tous les tests de la classe se moqueront de la classe cible.

** Code de test **

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge001;
import SampleProject.Hoge002;
import mockit.Expectations;
import mockit.Mocked;

public class Test001_2 {

	//Les instances simulées peuvent être utilisées dans chaque cas de test en les spécifiant comme champs de classe de test.
	@Mocked
	private Hoge001 fieldMocked;
	@Test
	public void test1() {
		new Expectations() {{
			fieldMocked.hoge(anyInt, anyInt);
			result = 100;
		}};
		assertEquals(100, fieldMocked.hoge(1,2));
	}
	@Test
	public void test2() {
		new Expectations() {{
			//hoge est x=10, y =S'il est appelé par 12, la première fois renvoie 99
			fieldMocked.hoge(10,12);
			result  = 99;
		}};
		Hoge002 hoge2 = new Hoge002();
		assertEquals(99, hoge2.test(5,6));
	}
}

Maquette en cascade

Supposons que vous ayez des fonctionnalités fournies à l'aide de nombreux objets différents. Il n'est pas rare d'avoir des appels tels que "obj1.getObj2 (...). GetYetAnotherObj (). DoSomething (...)". Regardons un exemple de simulation dans ce cas.

Dans l'exemple ci-dessous, le code consiste à vérifier si la moquerie est effectuée dans une méthode qui renvoie un objet tel que mock.getDepend1 (). Output ().

** Classe sous test **

package SampleProject;

public class Depend001 {
	private String prefix;
	public Depend001(String p) {
		this.prefix = p;
	}
	public String output(String msg) {
		return this.prefix + msg;
	}
}
package SampleProject;

public class Hoge003 {
	private Depend001 d1;
	public Depend001 d2;
	public Hoge003() {

	}

	public Hoge003(Depend001 depend1, Depend001 depend2) {
		this.d1 = depend1;
		this.d2 = depend2;
	}

	public String output() {
		String ret = "";
		ret = ret + this.d1.output("test1") + "\n";
		ret = ret + this.d2.output("test2") + "\n";
		return ret;
	}
	public Depend001 getDepend1() {
		return this.d1;
	}
}

** Code de test **

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge003;
import mockit.Expectations;
import mockit.Mocked;

public class Test002 {
	@Test
	public void test1(@Mocked Hoge003 mock) {
		new Expectations() {{
			mock.getDepend1().output(anyString);
			result  = "abcde";
		}};
		assertEquals("abcde", mock.getDepend1().output("abc"));
	}

}

Comme dans l'exemple ci-dessus, il a été confirmé que se moquer de la classe Hoge003 d'origine modifie le comportement attendu de la méthode cible sans se moquer explicitement de la branche et de la feuille Depend001.

@ Annotation injectable

Comme l'annotation @Mocked, il s'agit d'une annotation pour se moquer, mais la différence avec l'annotation @Mocked est que la maquette est limitée à une seule instance. Il peut également être utilisé pour l'injection automatique dans l'objet sous test en combinaison avec l'annotation @Tested.

Différence par rapport à l'annotation @Mocked

Pour voir la différence entre les annotations @Mocked et @Injectable, remplacez le code de test utilisé dans l'annotation @Mocked par @Injectable et vérifiez.

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge001;
import mockit.Expectations;
import mockit.Injectable;

public class Test004 {

	//Vous pouvez créer une instance simulée en la spécifiant comme paramètre de la méthode de test
	@Test
	public void test1(@Injectable Hoge001 mock) {
		new Expectations() {{
			//hoge est x=5, y =S'il est appelé par 6, renvoie 99 la première fois
			mock.hoge(5,6);
			result  = 99;
		}};
		//Si vous spécifiez un résultat de méthode dans les attentes, cette valeur est récupérée
		assertEquals(99, mock.hoge(5,6));
		//Valeur par défaut si les attentes ne spécifient pas de résultat de méthode(null)Devient
		assertEquals(null, mock.hoge("xxx"));

		// @Toutes les instances applicables ne sont pas simulées, comme c'est le cas avec Mocked.
		Hoge001 hoge = new Hoge001();
		assertEquals(11, hoge.hoge(5,6));
		assertEquals("testxxx", hoge.hoge("xxx"));

	}
}

Lors de l'utilisation de l'annotation @Mocked, elle était simulée à chaque fois qu'une instance de la classe cible était créée pendant la période de test, mais en utilisant @Injectable, le nombre d'instances simulées est limité à une. Vous pouvez voir que vous le faites.

Injection pour l'annotation @Tested

Vérifions l'exemple qui injecte une maquette dans l'objet à tester spécifié par l'annotation @Tested. Il existe deux méthodes, l'une consiste à injecter dans l'argument du constructeur de l'objet à tester spécifié par @Tested, et l'autre à injecter dans le champ à tester.

** Comment injecter dans les arguments du constructeur ** Voici un exemple de spécification de depend1 et depend2, qui sont les arguments du constructeur de Hoge003 (Depend001 depend1, Depend001 depend2).

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Depend001;
import SampleProject.Hoge003;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Tested;

public class Test003 {
	@Tested
	Hoge003 target;

	@Injectable
	Depend001 depend1;

	@Injectable
	Depend001 depend2;

	@Test
	public void test1() {
		new Expectations() {{
			depend1.output(anyString);
			result  = "abcde";
			depend2.output(anyString);
			result  = "xxxxx";
		}};
		assertEquals("abcde\nxxxxx\n", target.output());
	}

}

** Comment injecter sur le terrain ** Voici un exemple à injecter dans les champs d1 et d2 de l'objet Hoge003.

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Depend001;
import SampleProject.Hoge003;
import mockit.Expectations;
import mockit.Injectable;
import mockit.Tested;

public class Test003B {
	@Tested
	Hoge003 target;

	@Injectable
	Depend001 d1;

	@Injectable
	Depend001 d2;

	@Test
	public void test1() {
		new Expectations() {{
			d1.output(anyString);
			result  = "abcde";
			d2.output(anyString);
			result  = "xxxxx";
		}};
		assertEquals("abcde\nxxxxx\n", target.output());
	}
}
Comment injecter dans un champ primitif ou une construction

En utilisant l'élément value de l'annotation @Injectable, il est possible d'injecter dans le champ ou la construction du type primitif à tester spécifié par l'annotation @Tested.

package jmockittest;

import org.junit.Test;

import SampleProject.Depend001;
import mockit.Injectable;
import mockit.Tested;

public class Test005 {
	@Tested
	Depend001 tested;

	@Test
	public void test1(@Injectable("abc") String p) {
		//Sortie de ce qui suit
		// abcaaa
		System.out.println(tested.output("aaa"));
	}
	@Test
	public void test2(@Injectable("abc") String prefix) {
		//Sortie de ce qui suit
		// abcbbb
		System.out.println(tested.output("bbb"));
	}
}

test1 injecte en spécifiant l'argument constructeur p de l'objet à tester, et test2 injecte en spécifiant le préfixe de champ de l'objet à tester.

Élément facultatif de l'annotation @Tested
type Nom Éléments optionnels et description Valeur spécifiée
boolean availableDuringSetup La classe testée est la méthode de configuration du test (c'est-à-dire@Avant ou@Indique s'il est instancié et initialisé avant (une méthode annotée comme BeforeMethod) est exécuté, ou après eux. false
boolean fullyInitialized Indique qu'une valeur doit être attribuée à chaque champ non final d'un objet testé éligible pour l'injection. Si vous utilisez Spring, l'utilisation est décrite à la page suivante. https://stackoverflow.com/questions/25856210/injecting-only-some-properties-mocking-others false
boolean global Crée une seule instance nommée de la classe testée pour indiquer si elle sera utilisée tout au long du test. false
String value Champ à tester/Si le type de paramètre est une chaîne, un type primitif ou wrapper, un type numérique ou un type d'énumération, spécifiez une valeur littérale. ""

** Code de test pour vérifier la disponibilité pendant la configuration et global **

package jmockittest;

import org.junit.Before;
import org.junit.Test;

import SampleProject.Hoge001;
import mockit.Tested;

public class Test007 {
	@Tested(availableDuringSetup=true, global=true)
	Hoge001 tested;

	@Before
	public void before()
	{
		//Autre que null: si availableDuringSetup est false, il sera nul.
		System.out.println("before:" + tested);
	}

	@Test
	public void test1() {
		//Non nul
		System.out.println("test1:" + tested);
	}
	@Test
	public void test2() {
		//Vous pouvez voir que le même objet que test1 est utilisé sauf pour null
		System.out.println("test2:" + tested);
	}
}

@Capturing annotation

Vous pouvez vous moquer de la classe ou de l'interface par défaut à l'aide de l'annotation @Capturing. L'exemple ci-dessous est un exemple qui crée une méthode simulée pour une interface plutôt qu'une classe d'implémentation individuelle.

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import mockit.Capturing;
import mockit.Expectations;

public class Test006 {
	public interface Service { int doSomething(); }
	final class ServiceImpl implements Service { public int doSomething() { return 1; } }

	public final class TestedUnit {
	   private final Service service1 = new ServiceImpl();
	   private final Service service2 = new Service() { public int doSomething() { return 2; } };

	   public int businessOperation() {
	      return service1.doSomething() + service2.doSomething();
	   }
	}

	//Créer une maquette pour une interface ou une classe par défaut
	@Test
	public void test1(@Capturing Service anyService) {
	      new Expectations() {{ anyService.doSomething(); returns(3, 4); }};

	      int result = new TestedUnit().businessOperation();

	      assertEquals(7, result);
	}
}

Expectations Les attentes définissent le comportement attendu des objets fictifs associés à un test particulier.

Définissez la valeur attendue

Pendant les attentes, vous pouvez spécifier les paramètres à spécifier pour la méthode d'objet fictif et la valeur à renvoyer. Dans l'exemple ci-dessous, il s'agit d'un exemple de définition de la valeur renvoyée lorsque les méthodes "String hoge (String)" et "int hoge (int, int)" sont exécutées.

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import SampleProject.Hoge001;
import mockit.Delegate;
import mockit.Expectations;
import mockit.Mocked;

public class Test008 {

	//Si vous spécifiez le résultat de la méthode dans les attentes, assurez-vous que la valeur est obtenue.
	@Test
	public void test1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge("test");
			result = "abcde";

			mock.hoge(5,6);
			result  = 99;
			result = 100;
			result = 101;

		}};
		// mock.hoge("test")Obtenez la valeur attendue lors de l'exécution
		assertEquals("abcde", mock.hoge("test"));


		// mock.hoge(5,6)Obtenez la valeur attendue lors de l'exécution
		//Obtenez la première valeur définie dans les attentes
		assertEquals(99, mock.hoge(5,6));
		//Obtenez la deuxième valeur définie dans les attentes
		assertEquals(100, mock.hoge(5,6));
		//Obtenez la troisième valeur définie dans les attentes
		assertEquals(101, mock.hoge(5,6));
		//Obtenez la dernière valeur définie dans les attentes
		assertEquals(101, mock.hoge(5,6));
		//Obtenez la dernière valeur définie dans les attentes
		assertEquals(101, mock.hoge(5,6));

		//Si les arguments sont différents, ce sera la valeur initiale
		assertEquals(0, mock.hoge(7,6));
	}
}
Exemple décrit dans les retours

Plusieurs résultats peuvent être répertoriés ensemble dans les retours, comme indiqué ci-dessous.

		new Expectations() {{
			mock.hoge("test");
			result = "abcde";

			mock.hoge(5,6);
			returns(99, 100, 101);

		}};

Manière flexible de spécifier des arguments

Dans l'exemple précédent, la valeur de retour n'était renvoyée que lorsque la valeur d'un argument spécifique était acceptée, mais la valeur de l'argument peut être définie de manière flexible en spécifiant n'importe quel ~ ou avec ~ comme argument.

Utilisation de n'importe quel champ

Les attentes ont plusieurs champs qui représentent n'importe quel but.

type name
Object any
Boolean anyBoolean
Byte anyByte
Character anyChar
Double anyDouble
Float anyFloat
Integer anyInt
Long anyLong
Short anyShort
String anyString

Un exemple utilisant le champ any est le suivant.

	@Test
	public void test1_1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyString);
			result = "abcde";

			mock.hoge(anyInt, anyInt);
			result  = 99;

		}};
		// mock.hoge("test")Obtenez la valeur attendue lors de l'exécution
		assertEquals("abcde", mock.hoge("test"));
		assertEquals("abcde", mock.hoge("hogehoget"));


		// mock.hoge(5,6)Obtenez la valeur attendue lors de l'exécution
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
	}
Combinez des valeurs d'argument fixes avec des valeurs d'argument arbitraires

Vous pouvez également combiner des valeurs d'argument fixes avec des valeurs d'argument arbitraires. Dans l'exemple ci-dessous, créez une méthode fictive qui renvoie 10 pour hoge (5,6) et 99 sinon.

	@Test
	public void test1_2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(5,6);
			result = 10;

			mock.hoge(anyInt, anyInt);
			result  = 99;

		}};

		// mock.hoge(5,6)Obtenez la valeur attendue lors de l'exécution
		assertEquals(10, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
	}

Lors de la combinaison avec la valeur d'un argument, entrez d'abord la valeur fixe.

Utilisation de avec méthode

En utilisant la méthode with ~, il est possible de juger de manière flexible si elle correspond ou non à la méthode fictive spécifiée dans les attentes.

Méthode La description
with(Delegate<? super T> objectWithDelegateMethod) Utilisez la méthode déléguée pour déterminer si les arguments correspondent. Si la valeur de retour de la méthode déléguée est true, cela signifie une correspondance.
withEqual(T arg) Vérifie si la valeur spécifiée correspond à l'argument lors de l'exécution du simulacre. En général, n'utilisez pas cette méthode, mais utilisez la méthode de transmission de la valeur de l'argument souhaité.
withEqual(double value, double delta) On suppose que la correspondance est proche de la valeur spécifiée par delta.
withEqual(float value, double delta) On suppose que la correspondance est proche de la valeur spécifiée par delta.
withAny(T arg) Pensez à utiliser anyBoolean, anyByte, anyChar, anyDouble, anyFloat, anyInt, anyLong, anyShort, anyString, any.
withNotEqual(T arg) Si la valeur est différente de la valeur spécifiée, elle est considérée comme concordante.
withNotNull() Si la valeur spécifiée est non NULL, elle est considérée comme correspondant.
withNull() Si la valeur spécifiée est NULL, elle est supposée correspondre
withInstanceOf(Class argClass) Assurez-vous qu'il s'agit d'une instance de la classe spécifiée.
withInstanceLike(T object) Assurez-vous qu'il s'agit d'une instance de la même classe que l'objet spécifié. withInstanceOf(object.getClass())Sera équivalent à
withSameInstance(T object) Assurez-vous qu'il s'agit exactement de la même instance
withPrefix(T text) Si un caractère particulier est inclus, il est considéré comme une correspondance
withSubstring(T text) Si le début correspond au caractère spécifié, il est considéré comme correspondant.
withSuffix(T text) Si la fin correspond au caractère spécifié, il est considéré comme correspondant.
withMatch(T regex) Vous pouvez spécifier s'il faut faire correspondre avec une expression régulière
Exemple d'utilisation de la méthode déléguée avec with

En utilisant la méthode déléguée avec with, il est possible de juger si les arguments fictifs correspondent dans la méthode.

	@Test
	public void test1_4(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(with(new Delegate<Integer>() {
				@Mock boolean validate(int value) {
					return value >= 0;
				}
			}),anyInt);
			result = 99;
		}};


		//Puisque x est positif, il correspond à la valeur définie dans le simulacre
		assertEquals(99, mock.hoge(1,2));
		//Puisque x est négatif, il ne correspond pas à la valeur définie dans le simulacre
		assertEquals(0, mock.hoge(-1,2));
	}
Exemple d'utilisation de withEqual

Fondamentalement, il est préférable d'utiliser le littéral tel quel que d'utiliser withEqual. Cependant, si vous souhaitez utiliser une virgule flottante, vous devez utiliser withEqual.

	class testWithEqual {
		int test1(double v) {
			return 1000;
		}
		int test2(int v) {
			return 2000;
		}
	}

	@Test
	public void test_withEqual1(@Mocked testWithEqual mock) {
		new Expectations() {{
			mock.test2(withEqual(100));
			result = 99;
		}};
		//Maquette assortie.test2(100)Pareil que
		assertEquals(99, mock.test2(100));
		//Ça ne correspond pas
		assertEquals(0, mock.test2(101));
	}
	@Test
	public void test_withEqual2(@Mocked testWithEqual mock) {
		new Expectations() {{
			mock.test1(withEqual(100, 1));
			result = 99;
		}};
		//Rencontre
		assertEquals(99, mock.test1(100.0));
		assertEquals(99, mock.test1(101.0));
		assertEquals(99, mock.test1(99.0));
		//Ça ne correspond pas
		assertEquals(0, mock.test1(101.1));
		assertEquals(0, mock.test1(98.99));
	}

Exemples de withInstanceOf, withInstanceOf, withSameInstance

Vous pouvez utiliser withInstanceOf, withInstanceOf, withSameInstance pour voir si cela correspond à une instance particulière.

	class classA {
	}
	class classB {
	}
	class classX  {
		public int method1(Object obj) {
			return 999;
		}
	}

	@Test
	public void test_withInst1(@Mocked classX mock) {
		new Expectations() {{
			mock.method1(withInstanceOf(classA.class));
			result = 99;
		}};
		//Rencontre
		{
			classA obj = new classA();
			assertEquals(99, mock.method1(obj));
		}

		//Ça ne correspond pas
		{
			classB obj = new classB();
			assertEquals(0, mock.method1(obj));
		}
	}

	@Test
	public void test_withInst2(@Mocked classX mock) {
		new Expectations() {{
			classA objA = new classA();
			mock.method1(withInstanceLike(objA));
			result = 99;
		}};
		//Rencontre
		{
			classA obj = new classA();
			assertEquals(99, mock.method1(obj));
		}

		//Ça ne correspond pas
		{
			classB obj = new classB();
			assertEquals(0, mock.method1(obj));
		}
	}
	@Test
	public void test_withInst3(@Mocked classX mock) {
		classA obj1 = new classA();
		new Expectations() {{
			mock.method1(withSameInstance(obj1));
			result = 99;
		}};
		//Rencontre
		{
			assertEquals(99, mock.method1(obj1));
		}

		//Ça ne correspond pas
		{
			classA obj2 = new classA();
			assertEquals(0, mock.method1(obj2));
		}
	}
Exemples de withPrefix, withSubstring, withSuffix, withMatch

En utilisant withPrefix, withSubstring, withSuffix, withMatch, il est possible de vérifier si une partie de la chaîne de caractères correspond.

	@Test
	public void test_withString1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(withPrefix("abc"));
			result = "test";
		}};

		//Le match suivant
		assertEquals("test", mock.hoge("abc"));
		assertEquals("test", mock.hoge("abcAA"));

		//Les éléments suivants ne correspondent pas
		assertEquals(null, mock.hoge("AAabc"));
		assertEquals(null, mock.hoge("AabcA"));
		assertEquals(null, mock.hoge("xx"));
	}

	@Test
	public void test_withString2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(withSuffix("abc"));
			result = "test";
		}};

		//Le match suivant
		assertEquals("test", mock.hoge("abc"));
		assertEquals("test", mock.hoge("AAabc"));

		//Les éléments suivants ne correspondent pas
		assertEquals(null, mock.hoge("abcAA"));
		assertEquals(null, mock.hoge("AabcA"));
		assertEquals(null, mock.hoge("xx"));
	}
	@Test
	public void test_withString3(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(withSubstring("abc"));
			result = "test";
		}};

		//Le match suivant
		assertEquals("test", mock.hoge("abc"));
		assertEquals("test", mock.hoge("abcAA"));
		assertEquals("test", mock.hoge("AAabc"));
		assertEquals("test", mock.hoge("AabcA"));

		//Les éléments suivants ne correspondent pas
		assertEquals(null, mock.hoge("xx"));
	}
	@Test
	public void test_withString4(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(withMatch("[0-9]+"));
			result = "test";
		}};

		//Le match suivant
		assertEquals("test", mock.hoge("1234"));

		//Les éléments suivants ne correspondent pas
		assertEquals(null, mock.hoge("xxx"));
	}

Comment séparer les méthodes fictives en fonction de la façon dont l'instance est créée

Il est possible de diviser la méthode fictive en fonction de la façon dont l'instance est créée dans les attentes. L'exemple suivant montre un exemple qui applique la méthode fictive uniquement à l'instance créée en exécutant "new TestA (10)".

	class TestA {
		public TestA(int x) {

		}
		public int hoge() {
			return 99999;
		}
	}

	@Test
	public void test8(@Mocked TestA mock) {
		new Expectations() {{
			TestA t1 = new TestA(10);
			t1.hoge();
			result = 10;

		}};

		{
			TestA obj = new TestA(10);
			assertEquals(10, obj.hoge());
		}
		{
			TestA obj = new TestA(99);
			assertEquals(0, obj.hoge());
		}
	}

Comment lever une exception

Vous pouvez lever une exception lors du traitement d'une méthode fictive. L'exemple suivant déclenche une exception IllegalArgumentException lors de l'exécution de la méthode hoge ().

	//Un exemple de renvoi d'une exception de méthode dans les attentes
	@Test
	public void test2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(5,6);
			result = 99;
			result = new IllegalArgumentException("test");
		}};
		//Obtenez la première valeur définie dans les attentes
		assertEquals(99, mock.hoge(5,6));
		try {
			//Obtenez la deuxième valeur définie dans les attentes
			mock.hoge(5,6);
			fail();

		} catch (IllegalArgumentException ex) {
			assertEquals("test", ex.getMessage());
		}
	}

Vérifiez le nombre d'exécutions

Il est possible de spécifier le nombre d'exécutions d'une méthode en spécifiant times, maxTImes et minTimes dans les attentes.

Field Description
tiems Spécifie combien de fois la méthode est appelée pendant l'exécution. S'il est appelé un nombre de fois différent, une erreur se produira.
maxTimes Spécifie le nombre maximal de méthodes appelées. S'il est appelé plus de fois que cela, une erreur se produira.
minTimes Spécifie le nombre minimum de méthodes à appeler. Une erreur se produira si elle est appelée moins de ce nombre de fois.
	@Test
	public void test4_1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			times = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
	}
	//Ce test échoue avec 2 invocations manquantes
	@Test
	public void test4_2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			times = 3;

		}};
		assertEquals(99, mock.hoge(3,6));
	}

	//Ce test entraîne un appel inattendu et une erreur
	@Test
	public void test4_3(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			times = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
		assertEquals(99, mock.hoge(3,6));
	}

	@Test
	public void test5_1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			minTimes = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
	}

	//Ce test échoue avec 2 invocations manquantes
	@Test
	public void test5_2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			minTimes = 3;

		}};
		assertEquals(99, mock.hoge(3,6));
	}
	@Test
	public void test5_3(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			minTimes = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
		assertEquals(99, mock.hoge(3,6));
	}
	@Test
	public void test6_1(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			maxTimes = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
	}
	@Test
	public void test6_2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			maxTimes = 3;

		}};
		assertEquals(99, mock.hoge(3,6));
	}

	//Ce test entraîne un appel inattendu et une erreur
	@Test
	public void test6_3(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt, anyInt);
			result  = 99;
			maxTimes = 3;

		}};
		assertEquals(99, mock.hoge(5,6));
		assertEquals(99, mock.hoge(99,1234));
		assertEquals(99, mock.hoge(3,6));
		assertEquals(99, mock.hoge(3,6));
	}

Spécification personnalisée du résultat à l'aide de Delegate

Utilisez Deglegate si vous souhaitez modifier le résultat renvoyé par le simulacre en fonction des arguments lors de l'exécution de la méthode simulée. Dans l'exemple ci-dessous, nous créons une méthode fictive qui renvoie une valeur qui est le double de l'argument d'entrée.

	@Test
	public void test7(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt,anyInt);
			result= new Delegate<Integer>() {
				@SuppressWarnings("unused")
				int aDelegateMethod(int x, int y) {
					return x * 2 + y * 2;

		        }
		    };
		}};
		//Obtenez la première valeur définie dans les attentes
		assertEquals(22, mock.hoge(5,6));
	}

Utilisation de l'invocation

Il est possible d'utiliser Invocation comme premier paramètre de la méthode Delegate. Invocation propose les getters suivants:

Méthode La description
getInvocationCount() Nombre d'appels
getInvocationIndex() Obtenir l'index des appels en cours
getInvokedArguments() Récupère l'argument utilisé pour l'appel
getInvokedInstance() Instance de l'appel en cours. Null pour les méthodes statiques
getInvokedMember() Méthode d'appel/Obtenir le constructeur
proceed(Object... replacementArguments) Méthode réelle/Exécutez le constructeur
	@Test
	public void testDelegate2(@Mocked Hoge001 mock) {
		new Expectations() {{
			mock.hoge(anyInt,anyInt);
			result= new Delegate<Integer>() {
				@SuppressWarnings("unused")
				int aDelegateMethod(Invocation inv ,int x, int y) {
					System.out.println("--------------------------------");
					//Nombre d'appels
					System.out.format("Invocation getInvocationCount %d \n", inv.getInvocationCount());
					//Index de l'appel en cours
					System.out.format("Invocation getInvocationIndex() %d \n", inv.getInvocationIndex());
					//Obtenir l'argument
					System.out.println("getInvokedArguments");
					for(Object obj : inv.getInvokedArguments()) {
						System.out.println(obj);
					}
					//Obtenez une instance
					System.out.format("Invocation getInvokedInstance() %s \n", inv.getInvokedInstance().toString());
					//Obtenez la méthode actuelle
					System.out.format("Invocation getInvokedMember() %s \n", inv.getInvokedMember().toString());
					//La méthode réelle peut être exécutée.
					System.out.format("Invocation  proceed %s \n", inv.proceed().toString());
					//La méthode réelle peut être exécutée en altérant l'argument
					System.out.format("Invocation  proceed %s \n", inv.proceed(5,6).toString());
					return 0;
		        }
		    };
		}};
		//Obtenez la première valeur définie dans les attentes
		Hoge001 a = new Hoge001();
		Hoge001 b = new Hoge001();
		a.hoge(5,6);
		a.hoge(45,63);
		b.hoge(99,100);
	}

Le journal de la console qui a exécuté ce qui précède est le suivant.

--------------------------------
Invocation getInvocationCount 1 
Invocation getInvocationIndex() 0 
getInvokedArguments
5
6
Invocation getInvokedInstance() SampleProject.Hoge001@2a2d45ba 
Invocation getInvokedMember() public int SampleProject.Hoge001.hoge(int,int) 
Invocation  proceed 11 
Invocation  proceed 11 
--------------------------------
Invocation getInvocationCount 2 
Invocation getInvocationIndex() 1 
getInvokedArguments
45
63
Invocation getInvokedInstance() SampleProject.Hoge001@2a2d45ba 
Invocation getInvokedMember() public int SampleProject.Hoge001.hoge(int,int) 
Invocation  proceed 108 
Invocation  proceed 11 
--------------------------------
Invocation getInvocationCount 3 
Invocation getInvocationIndex() 2 
getInvokedArguments
99
100
Invocation getInvokedInstance() SampleProject.Hoge001@675d3402 
Invocation getInvokedMember() public int SampleProject.Hoge001.hoge(int,int) 
Invocation  proceed 199 
Invocation  proceed 11 

Partie simulée d'un objet

Pour simuler uniquement certaines des méthodes au lieu de toutes, passez l'objet à Expectations comme suit:

	@Test
	public void test10() {
		Hoge001 hoge = new Hoge001();
		new Expectations(hoge) {{
			hoge.hoge(5,6);
			result = 99;
		}};
		//Renvoie le résultat du simulacre
		assertEquals(99, hoge.hoge(5,6));
		
		//Exécuter la méthode réelle
		assertEquals(3, hoge.hoge(1,2));
		assertEquals("testabc", hoge.hoge("abc"));

	}

Verifications Vous pouvez utiliser Verifications, VerificationsInOrder et FullVerifications pour vérifier explicitement comment un objet fictif a été appelé.

	@Test
	public void test_v1(@Mocked Hoge001 mock) {
		mock.hoge(1,2);
		mock.hoge(2,3);
		mock.hoge(4,5);

		//
		new Verifications() {{
			mock.hoge(anyInt,anyInt);
			times = 3;
			mock.hoge(anyString);
			times = 0;
		}};
		//Les vérifications considèrent les appels hors service ou les appels supplémentaires à passer
		new Verifications() {{
			mock.hoge(4,5);
			mock.hoge(1,2);
		}};
	}
	@Test
	public void test_v2(@Mocked Hoge001 mock) {
		mock.hoge(1,2);
		mock.hoge(2,3);
		mock.hoge(4,5);

		//VerificationsInOrder entraînera une erreur si la commande est différente
		/*
		new VerificationsInOrder() {{
			mock.hoge(4,5);
			mock.hoge(1,2);
		}};
		*/
		new VerificationsInOrder() {{
			mock.hoge(1,2);
			mock.hoge(4,5);
		}};
	}
	@Test
	public void test_v3(@Mocked Hoge001 mock) {
		mock.hoge(1,2);
		mock.hoge(2,3);
		mock.hoge(4,5);

		//Les vérifications complètes entraîneront une erreur si des appels supplémentaires sont effectués
		/*
		new FullVerifications() {{
			mock.hoge(1,2);
			mock.hoge(4,5);
		}};
		*/
		new FullVerifications() {{
			mock.hoge(1,2);
			mock.hoge(2,3);
			mock.hoge(4,5);
		}};
		//Cela passera même si l'ordre est différent
		new FullVerifications() {{
			mock.hoge(4,5);
			mock.hoge(2,3);
			mock.hoge(1,2);
		}};
	}
Exemple de vérification utilisant withCapture

AvecCapture, vous pouvez obtenir une instance avec n'importe quel paramètre de List.

	//Exemple de vérification des paramètres avec withCapture
	@Test
	public void test_v4(@Mocked Hoge001 mock) {
		mock.hoge(1,2);
		mock.hoge(2,3);
		mock.hoge(4,5);

		//
		new Verifications() {{
			List<Integer> argXList = new ArrayList<Integer>();
			List<Integer> argYList = new ArrayList<Integer>();
			mock.hoge(withCapture(argXList),withCapture(argYList));
			assertEquals(3, argXList.size());
			assertEquals(3, argYList.size());

			assertEquals(1, (int)argXList.get(0));
			assertEquals(2, (int)argXList.get(1));
			assertEquals(4, (int)argXList.get(2));

			assertEquals(2, (int)argYList.get(0));
			assertEquals(3, (int)argYList.get(1));
			assertEquals(5, (int)argYList.get(2));

		}};
	}

	//Exemple de confirmation de la création d'instance avec withCapture
	class Person {
		public Person(String name , int age) {
		}
	}
	@Test
	public void test_v5(@Mocked Person mockPerson) {
		new Person("Joe", 10);
		new Person("Sara", 15);
		new Person("Jack", 99);

		//
		new Verifications() {{
			List<Person> created = withCapture(new Person(anyString, anyInt));
			assertEquals(3, created.size());

		}};
	}

Faking API L'API Faking fournit un support pour la création de fausses implémentations. Fake cible généralement certaines méthodes et constructeurs de la classe Fake, et la plupart des autres méthodes et constructeurs restent inchangés.

méthode publique / protégée Faux

Dans l'exemple suivant, seul Proc1 de la classe dans laquelle Proc1 et Proc2 existent est Fake.

package jmockittest;

import static org.junit.Assert.*;

import org.junit.Test;

import mockit.Mock;
import mockit.MockUp;

public class FakeTest {
	class ClassA {
		protected String Proc1() {
			return "...Proc1";
		}
		public String Proc2() {
			return  "Proc2:" + this.Proc1();
		}

	}
	@Test
	public void test1() {
        new MockUp<ClassA>() {

        	@Mock
        	String Proc1() {
        		System.out.print("Proc1");
        		return "xxx";
        	}
        };
        ClassA obj = new ClassA();
        assertEquals("Proc2:xxx", obj.Proc2());
	}
}

Méthode privée Faux

Pas possible avec 1.48. J'obtiens l'erreur suivante:

java.lang.IllegalArgumentException: Unsupported fake for private method ClassA#Proc1()Ljava/lang/String; found
	at jmockittest.FakeTest$1.<init>(FakeTest.java:22)
	at jmockittest.FakeTest.test1(FakeTest.java:22)

Probablement, il semble que cela a été fait avant et ne peut pas être fait. https://github.com/jmockit/jmockit1/issues/605

Exemple de méthode statique

La falsification de la méthode statique est possible. L'exemple ci-dessous est un exemple de java.lang.Math.random qui renvoie toujours une valeur fixe.

	@Test
	public void test() {
        new MockUp<java.lang.Math>() {
        	@Mock
        	public double random() {
        		//Toujours 2.Renvoie aléatoire 5()Méthode
        		return 2.5;
        	}
        };
		assertEquals(2.5, Math.random(), 0.1);
		assertEquals(2.5, Math.random(), 0.1);
	}

Est-il possible de créer un faux pour une méthode spécifiée par finail?

Il était possible de créer.

	class ClassB {
		final protected String Proc1() {
			return "...Proc1";
		}
		public String Proc2() {
			return  "Proc2:" + this.Proc1();
		}

	}
	@Test
	public void test3() {
        new MockUp<ClassB>() {

        	@Mock
        	String Proc1() {
        		System.out.print("Proc1");
        		return "xxx";
        	}
        };
        ClassB obj = new ClassB();
        assertEquals("Proc2:xxx", obj.Proc2());
	}

Méthodes spéciales dans la classe Fake

Il y a \ $ init, \ $ clinic, \ $ conseils comme méthodes spéciales dans la classe Fake. \ $ init cible le constructeur. \ $ clinic est destiné aux initialiseurs statiques. \ $ Advice représente toutes les méthodes de la classe cible.

** Cible de test **

ClassC.java


package SampleProject;

public class ClassC {
	public static int sx;
	private int x;
	static {
		sx = 999;
	}
	public ClassC(int x) {
		this.x = x;
	}

	public String Proc1() {
		System.out.format("ClassC Proc1 %d %d\n", sx, this.x);
		return "...Proc1";
	}

}

** Code de test **

	@Test
	public void test4() {
        new MockUp<ClassC>() {
        	@Mock
        	void $clinit() {
        		//Confirmez que l'initialisation statique de ClassiC ne fonctionne pas
        		assertEquals(0, ClassC.sx);
        	}

        	@Mock
        	void $init(int x) {
        		assertEquals(100, x);
        	}

        	@Mock
        	Object $advice(Invocation inv) {
				return "test";
        	}
        };
        ClassC obj = new ClassC(100);
        assertEquals("test", obj.Proc1());

	}

Paramètres spéciaux de la méthode Fake

Il est possible d'utiliser [Invocation](en utilisant #invocation) comme premier paramètre de la méthode Fake. Vous trouverez ci-dessous un exemple qui l'utilise pour renvoyer une valeur fixe pour l'heure actuelle.

	@Test
	public void testTime() {
		Calendar nowCalendar = Calendar.getInstance();
		System.out.println("Date et heure actuelles: " + nowCalendar.getTime());
        new MockUp<Calendar>() {
        	@Mock
        	Calendar getInstance(Invocation inv) {
        		Calendar cal = inv.proceed();
        		cal.set(Calendar.YEAR, 2018);
        		cal.set(Calendar.MONTH, 0);
        		cal.set(Calendar.DAY_OF_MONTH, 1);
        		cal.set(Calendar.HOUR, 22);
        		cal.set(Calendar.MINUTE, 32);
        		cal.set(Calendar.SECOND, 12);
        		cal.set(Calendar.MILLISECOND, 512);
        		return cal;
        	}
        	@Mock
        	Calendar getInstance(Invocation inv, TimeZone zone, Locale aLocale) {
        		Calendar cal = inv.proceed();
        		cal.set(Calendar.YEAR, 2018);
        		cal.set(Calendar.MONTH, 0);
        		cal.set(Calendar.DAY_OF_MONTH, 1);
        		cal.set(Calendar.HOUR, 22);
        		cal.set(Calendar.MINUTE, 32);
        		cal.set(Calendar.SECOND, 12);
        		cal.set(Calendar.MILLISECOND, 512);
        		return cal;
        	}
        };
        final Calendar c = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        assertEquals("20180102103212512", sdf.format(c.getTime()));

	}

Mesure de la couverture

Les résultats de la mesure de la couverture peuvent être générés en donnant des arguments VM dans la configuration d'exécution.

-Dcoverage-output=html -Dcoverage-srcDirs=..\SampleProject\src

image.png

image.png

image.png

Voir ci-dessous pour d'autres arguments. http://jmockit.github.io/tutorial/CodeCoverage.html

En tant que comportement non documenté, "-Dcoverage-output = xml" semble produire du XML.

Résumé

J'ai fait des recherches jusqu'à présent, mais en regardant la discussion autour de la méthode privée sur GitHub et l'historique de l'abolition de l'historique des mises à jour, je pense que c'est un peu risqué à utiliser si vous n'êtes pas dans un environnement de test idéal complet et parfait. ..

De plus, j'ai également vérifié powermock + mockito ci-dessous.

** Essayez d'utiliser powermock-mockito2-2.0.2 ** https://qiita.com/mima_ita/items/3574a03b3379fb5f3c3c

Recommended Posts

Essayez d'utiliser jmockit 1.48
Essayez d'utiliser libGDX
Essayez d'utiliser Maven
Essayez d'utiliser SwiftLint
Essayez d'utiliser Log4j 2.0
Essayez d'utiliser le Framework Axon
Essayez d'utiliser l'API REST de JobScheduler
Essayez d'utiliser la méthode java.lang.Math
Essayez d'utiliser la WhiteBox de PowerMock
Essayez d'utiliser Talend Part 2
Essayez d'utiliser Talend Part 1
Essayez d'utiliser la liste F #
Essayez d'utiliser la méthode each_with_index
Essayez d'utiliser Spring JDBC
Essayez d'utiliser GloVe avec Deeplearning4j
Essayez de gratter en utilisant Java [Note]
Essayez d'utiliser Cocoa de Ruby
Essayez d'utiliser IntelliJ IDEA car vous ne devez le faire qu'une seule fois
Essayez d'utiliser Spring Boot Security
[Rails] Essayez d'utiliser le middleware de Faraday
[Traitement] Essayez d'utiliser GT Force.
[Programmation complète] §2 Essayez d'utiliser Ruby
Essayez Redmine sur le docker Mac
Essayez d'utiliser Redis avec Java (jar)
[Java] Essayez de mettre en œuvre à l'aide de génériques
Essayez d'utiliser le système de messagerie Pulsar
Essayez d'utiliser le traçage de méthode IBM Java
Essayez d'utiliser le SDK Java d'Hyperledger Iroha
[Java] Où avez-vous essayé d'utiliser java
Essayez d'utiliser le framework Java Nablarch [Application Web]
Essayez d'utiliser || au lieu de l'opérateur ternaire
Essayez HiveRunner
Essayez d'utiliser le service sur Android Oreo
Essayez d'utiliser l'API Stream en Java
Essayez Mockito
Étude de Java Essayez d'utiliser un scanner ou une carte
Essayez le sélénium
Essayez d'utiliser l'API au format JSON en Java
Essayez DbUnit
Essayez d'utiliser Spring Boot avec VS Code
Essayez d'utiliser MT Loader de Reladomo (chargeur de matrices multi-threads)
Essayez d'utiliser l'API REST de JobScheduler - implémentation Java RestClient--
Essayez d'utiliser l'API Emotion d'Android
Essayez d'utiliser la télécommande Wii en Java
Essayez Lombok
Essayez d'utiliser simple_form / modifier même les modèles enfants
Essayez d'implémenter un serveur GraphQL en utilisant grahpql-java-tools (+ kotlin)
Essayez d'utiliser Firebase Cloud Functions sur Android (Java)
Essayez d'utiliser la classe de test RestClient de JobScheduler REST-API-Java-
Les débutants essaient d'utiliser Android Studio Partie 2 (traitement des événements)