0% ont trouvé ce document utile (0 vote)
3 vues146 pages

Cours Java Jun It

Le document présente une introduction aux tests unitaires en utilisant JUnit 5 et Mockito 3, en détaillant les concepts de base tels que les assertions, les méthodes de test et les annotations. Il explique également comment créer des cas de test, exécuter des tests et gérer les exceptions. L'objectif principal est de maximiser la détection des bugs pour améliorer la qualité du code.

Transféré par

risalafr
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
3 vues146 pages

Cours Java Jun It

Le document présente une introduction aux tests unitaires en utilisant JUnit 5 et Mockito 3, en détaillant les concepts de base tels que les assertions, les méthodes de test et les annotations. Il explique également comment créer des cas de test, exécuter des tests et gérer les exceptions. L'objectif principal est de maximiser la détection des bugs pour améliorer la qualité du code.

Transféré par

risalafr
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Les tests unitaires avec JUnit 5 et Mockito 3

Achref El Mouelhi

Docteur de l’université d’Aix-Marseille


Chercheur en programmation par contrainte (IA)
Ingénieur en génie logiciel

[Link]@[Link]

H & H: Research and Training 1 / 103


Plan

1 Introduction

2 Premier exemple

3 Assertions

4 Suppositions

5 Pre/Post test

6 Mockito

H & H: Research and Training 2 / 103


Plan
7 Quelques méthodes pour les mocks
mock
when ... thenReturn
doReturn ... when
verify
times
atLeast
any
anyInt
never
only
inOrder
when ... thenAnswer
doAnswer ... when
when ... thenThrow
doThrow ... when
spy

H & H: Research and Training 3 / 103


Plan

8 Capture d’arguments

9 Quelques annotations pour les mocks


@Mock
@ExtendWith
@InjectMocks
@Spy
@Captor

10 JUnit et Maven

H & H: Research and Training 4 / 103


Plan

11 Quelques annotations pour les tests


@RunWith
@DisplayName
@Disabled
@RepeatedTest
@ParameterizedTest
@DisabledOnOs et @EnabledOnOs
@DisabledOnJre et @EnabledOnJre
@DisabledIf et @EnabledIf

12 Recouvrement du code

H & H: Research and Training 5 / 103


Introduction

JUnit
JUnit ?

Framework open-source pour Java créé par Kent Beck et Erich Gamma.

Permettant d’automatiser les tests et de s’assurer que le programme répond


toujours aux besoins.
H I ©
Basé sur les assertions qui vérifient si les résultatsE
U L
de tests correspondent aux
résultats attendus.
L MO
Membre de la famille XUnit f
r e E pour C++, CUnit pour C, PHPUnit pour
(CPPUnit
PHP...).
A ch
©

H & H: Research and Training 6 / 103


Introduction

JUnit
JUnit ?

Framework open-source pour Java créé par Kent Beck et Erich Gamma.

Permettant d’automatiser les tests et de s’assurer que le programme répond


toujours aux besoins.
H I ©
Basé sur les assertions qui vérifient si les résultatsE
U L
de tests correspondent aux
résultats attendus.
L MO
Membre de la famille XUnit f
r e E pour C++, CUnit pour C, PHPUnit pour
(CPPUnit
PHP...).
A ch
©
Objectif

Trouver un maximum de bugs pour les corriger.

H & H: Research and Training 6 / 103


Introduction

JUnit

TestCase (cas de test)


Classe Java

H I ©
Contenant quelques méthodes de test (annotées par @Test)
UEL
O
Permettant de tester le bon fonctionnement d’une classe (en
testant ses méthodes)
f E LM
ch r e
©A
Remarque

Si le test ne détecte pas d’erreur ; il n’y en a pas.

H & H: Research and Training 7 / 103


Premier exemple

JUnit

Étape

Création d’un Java Project


H I ©
U
Création de deux Package : [Link] et
[Link]
L MO
e éféeE
h r
Pour chaque classe cr dans [Link], on lui
Ac de test (dans [Link])
associe une classe
©
On prépare le test et ensuite on le lance : s’il y a une erreur, on la
corrige et on relance le test.

H & H: Research and Training 8 / 103


Premier exemple

JUnit

Création d’une première classe Calcul


package [Link];

public class Calcul {


H I ©
public int somme(int x, int y) {
UEL
return x + y; O
}
f E LM
ch r e
public int division(int x, int y) {

©A
if (y == 0)
throw new ArithmeticException();
return x / y;
}
}

H & H: Research and Training 9 / 103


Premier exemple

JUnit
Pour créer une classe de test

Faire un clic droit sur le package [Link]

Aller dans New > JUnit Test Case

Saisir le nom CalculTest dans Name


H I ©
UEL
O
Cocher les 4 cases de Which method stubs would you like to
create ?
f E LM
ch r e
Cliquer sur Browse en face de Class under test

©A
Chercher calcul, sélectionner Calcul - [Link] et valider

Cliquer sur Next puis cocher les cases correspondantes de somme et


division dans Calcul

Cliquer sur Finish puis sur ok (pour valider Add JUnit 5 library to the
build path dans Perform the following action:)

H & H: Research and Training 10 / 103


Premier exemple

Le code généré :
package [Link];

import static [Link].*;

import [Link];

class CalculTest {
@BeforeAll
H I ©
EL
static void setUpBeforeClass() throws Exception { }
@AfterAll

O U
static void tearDownAfterClass() throws Exception { }
@BeforeEach
void setUp() throws Exception {
f E} LM
@AfterEach
ch r e
void tearDown() throws Exception { }
@Test
void testSomme() {©A
fail("Not yet implemented");
}
@Test
void testDivision() {
fail("Not yet implemented");
}
}

H & H: Research and Training 11 / 103


Premier exemple

JUnit
Nous parlerons de ces quatre méthodes dans une autre section
@BeforeAll
static void setUpBeforeClass() throws Exception {
}

H I ©
@AfterAll
UEL
O
static void tearDownAfterClass() throws Exception {
}
f E LM
@BeforeEach
ch r e
©A
void setUp() throws Exception {
}

@AfterEach
void tearDown() throws Exception {
}

H & H: Research and Training 12 / 103


Premier exemple

JUnit

Pour tester
Faire un clic droit sur le la classe de test
H I ©
Aller dans Run As > JUnit Test
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 13 / 103


Premier exemple

JUnit

Pour tester
Faire un clic droit sur le la classe de test
H I ©
Aller dans Run As > JUnit Test
UEL
O
f E LM
ch r e
Résultat
©A
2 Exécutions : 2 Échecs : car les deux méthodes de test sont vides.

H & H: Research and Training 13 / 103


Premier exemple

JUnit
Implémentons testSomme() en ciblant chaque fois les cas particuliers
void testSomme() {
Calcul calcul = new Calcul();
if ([Link](2, 3) != 5)
fail("faux pour deux entiers positifs");
if ([Link](-2, -3) != -5)
H I ©
fail("faux pour deux entiers négatifs");
UEL
O
LM
if ([Link](-2, 3) != 1)

if ([Link](0, 3) != 3)
r e E
fail("faux pour deux entiers de signe différent");
f
ch
©A
fail("faux pour x nul");
if ([Link](2, 0) != 2)
fail("faux pour y nul");
if ([Link](0, 0) != 0)
fail("faux pour x et y nuls");
}

H & H: Research and Training 14 / 103


Premier exemple

JUnit
Implémentons testSomme() en ciblant chaque fois les cas particuliers
void testSomme() {
Calcul calcul = new Calcul();
if ([Link](2, 3) != 5)
fail("faux pour deux entiers positifs");
if ([Link](-2, -3) != -5)
H I ©
fail("faux pour deux entiers négatifs");
UEL
O
LM
if ([Link](-2, 3) != 1)

if ([Link](0, 3) != 3)
r e E
fail("faux pour deux entiers de signe différent");
f
ch
©A
fail("faux pour x nul");
if ([Link](2, 0) != 2)
fail("faux pour y nul");
if ([Link](0, 0) != 0)
fail("faux pour x et y nuls");
}

En testant, plus d’échec pour somme.


H & H: Research and Training 14 / 103
Assertions

JUnit

Remarques

Pour tester une méthode, on peut aussi utiliser les assertions ou les
assmptions.

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 15 / 103


Assertions

JUnit

Remarques

Pour tester une méthode, on peut aussi utiliser les assertions ou les
assmptions.

H I ©
U EL
O
Assertions
f E LM
r e
ch définies dans la classe Assertions.
Méthodes statiques
© A
Permettant de vérifier le bon déroulement d’un test : si la
vérification échoue, l’assertion lève une exception et le test
échoue.
Acceptant depuis la version 5 les expressions Lambda.

H & H: Research and Training 15 / 103


Assertions

Quelques assertions

assertTrue(condition, message) : permet de vérifier que la condition fournie en


paramètre est vraie.

assertFalse(condition, message) : permet de vérifier que la condition fournie en


paramètre est fausse.

I ©
assertEquals(valeur attendue, appel de méthode, message) : permet de
H
EL
vérifier l’égalité de valeur (sa réciproque est assertNotEquals).

O U
assertSame(objet attendu, objet retourné, message) : permet de vérifier si

assertNotSame).
f E LM
objet attendu et objet retourné réfèrent le même objet (sa réciproque est

ch r e
assertArrayEquals(tableau attendu, tableau retourné, message) :

©A
permet de vérifier l’égalité de deux tableaux.

assertIterableEquals(iterable attendu, iterable retourné, message) :


permet de vérifier l’égalité de deux itérables.

assertNotNull(message, object) permet de vérifier, pour les paramètres utilisés,


qu’une méthode ne retourne pas la valeur null (sa réciproque est assertNull).

...

H & H: Research and Training 16 / 103


Assertions

JUnit

Remarques
H I ©
EL
En l’absence d’un message explicite, un message d’erreur par
défaut sera affiché.
M OU
f
Les méthodes assertX()E L aussi avoir la signature
peuvent
c hr e
suivante : assertX(message, valeurAttendue,
© A
appelDeMéthodeATester)

H & H: Research and Training 17 / 103


Assertions

Implémentons la méthode testDivision()

void testDivision() {
Calcul calcul = new Calcul();
assertFalse([Link](6, 3) == 0, "2 entiers positifs");
assertEquals(2, [Link](-6, -3), "2 entiers négatifs");
assertNotNull([Link](-6, 3), "2 entiers de signe diff");
assertTrue([Link](0, 3) == 0, "entier x nul");
Throwable e = null;
try {
H I ©
EL
[Link](2, 0);
}
O U
LM
catch (Throwable ex) {
e = ex;
}
r e f E
ch
assertTrue(e instanceof ArithmeticException);

©A
e = null;
try {
[Link](0, 0);
}
catch (Throwable ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 18 / 103


Assertions

JUnit

Ajouter des valeurs erronées pour avoir un échec


H I ©
EL
Le message défini sera affiché dans le panneau Failure Trace
U
O
(vous pouvez cliquer sur l’icône d’écran, Show Stack Trace

f E LM
in Console View, en face Failure Trace pour visualiser les
r e
détails de l’erreur dans la console).
ch
©A
Dans ce cas, il faut localiser l’erreur, la corriger et relancer.

H & H: Research and Training 19 / 103


Assertions

Par exemple, les deux premières assertions ne sont plus correctes

void testDivision() {
Calcul calcul = new Calcul();
assertFalse([Link](6, 3) == 2, "2 entiers positifs");
assertEquals(1, [Link](-6, -3), "2 entiers négatifs");
assertNotNull([Link](-6, 3), "2 entiers de signe diff");
assertTrue([Link](0, 3) == 0, "entier x nul");
Throwable e = null;
try {
H I ©
EL
[Link](2, 0);
}
O U
LM
catch (Throwable ex) {
e = ex;
}
r e f E
ch
assertTrue(e instanceof ArithmeticException);

©A
e = null;
try {
[Link](0, 0);
}
catch (Throwable ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 20 / 103


Assertions

JUnit

Constats

H I ©
Deux assertions incorrectes mais une seule exception retournée.
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 21 / 103


Assertions

JUnit

Constats

H I ©
Deux assertions incorrectes mais une seule exception retournée.
UEL
O
f E LM
Solution ch r e
©A
Regrouper les assertions avec assertAll

H & H: Research and Training 21 / 103


Assertions

JUnit

Regroupons les assertions avec assertAll

void testDivision() {
Calcul calcul = new Calcul();
assertAll("premier regroupement",
() -> assertFalse([Link](6, 3) == 2, "2 entiers positifs"),

I ©
() -> assertEquals(1, [Link](-6, -3), "2 entiers négatifs"),

H
() -> assertNotNull([Link](-6, 3), "2 entiers de signe diff"),

EL
() -> assertTrue([Link](0, 3) == 0, "entier x nul")
);
Throwable e = null;
O U
LM
try {
[Link](2, 0);
} catch (Throwable ex) {
e = ex;
r e f E
}
ch
©A
assertTrue(e instanceof ArithmeticException);
e = null;
try {
[Link](0, 0);
} catch (Throwable ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 22 / 103


Assertions

JUnit

En lançant les tests précédents, les deux échecs sont signalés ainsi que le nom du
regroupement
H I ©
U EL
[Link]: premier regroupement (2 failures)
O
LM
[Link]: 2 entiers positifs ==>
expected: <false> but was: <true>

f E
[Link]: 2 entiers négatifs ==>
r e
ch
expected: <1> but was: <2>

©A

H & H: Research and Training 23 / 103


Suppositions

JUnit

Assumptions (suppositions)
H I ©
U
Méthodes statiques définies dans la classe L
EAssumptions.
L
Permettant de conditionner l’ex MO d’un bloc de test : si
écution
r e f E échoue, le test sera désactivé sans
l’évaluation de l’assumption
être échoué.Ach
©

H & H: Research and Training 24 / 103


Suppositions

Modifions testDivision() pour que l’ensemble de tests précédents ne soit exécuté que
si on travaille dans un environnement Windows

void testDivision() {
Calcul calcul = new Calcul();
assumeTrue([Link]("OS").startsWith("Windows"));
assertFalse([Link](6, 3) == 0, "2 entiers positifs");
assertEquals(2, [Link](-6, -3), "2 entiers négatifs");
assertNotNull([Link](-6, 3), "2 entiers de signe diff");
assertTrue([Link](0, 3) == 0, "entier x nul");
H I ©
EL
Throwable e = null;
try {
O U
LM
[Link](2, 0);
} catch (Throwable ex) {
e = ex;
r e f E
ch
}

©A
assertTrue(e instanceof ArithmeticException);
e = null;
try {
[Link](0, 0);
} catch (Throwable ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 25 / 103


Suppositions

ou en utilisant assumingThat() fonctionnant avec une expression Lambda

void testDivision() {
Calcul calcul = new Calcul();
assumingThat([Link]("OS").startsWith("Windows"), () -> {
assertFalse([Link](6, 3) == 0, "2 entiers positifs");
assertEquals(2, [Link](-6, -3), "2 entiers négatifs");
assertNotNull([Link](-6, 3), "2 entiers de signe diff");
assertTrue([Link](0, 3) == 0, "entier x nul");
Throwable e = null;
H I ©
EL
try {
[Link](2, 0);
O U
LM
} catch (Throwable ex) {
e = ex;
}
r e f E
ch
assertTrue(e instanceof ArithmeticException);

©A
e = null;
try {
[Link](0, 0);
} catch (Throwable ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
});
}

H & H: Research and Training 26 / 103


Suppositions

JUnit

Quelques assumptions
assumeTrue()
H I ©
assumeFalse()
UEL
O
assumeThat()
f E LM
assumingThat()
ch r e
©A
assumeNoException()
assumeNotNull() :

H & H: Research and Training 27 / 103


Pre/Post test

JUnit

Dans certains cas

Avant de démarrer un test, il faut faire certains traitements :

instancier un objet de la classe,


se connecter à une base de données, H I ©
U EL
ouvrir un fichier...
O
E LM
Après le test, il faut aussi fermer certaines ressources : connexion à une base de données,
f
socket...

ch r e
©A

H & H: Research and Training 28 / 103


Pre/Post test

JUnit

Dans certains cas

Avant de démarrer un test, il faut faire certains traitements :

instancier un objet de la classe,


se connecter à une base de données, H I ©
U EL
ouvrir un fichier...
O
E LM
Après le test, il faut aussi fermer certaines ressources : connexion à une base de données,
f
socket...

ch r e
©A
Solution

On peut utiliser les méthodes setUp() et tearDown() qui sont respectivement exécutées
avant et après l’appel de chaque méthode de test.

H & H: Research and Training 28 / 103


Pre/Post test

Reprenons les quatre méthodes précédentes et modifions le code

@BeforeAll
static void setUpBeforeClass() throws Exception {
[Link]("BeforeAll");
}

@AfterAll
static void tearDownAfterClass() throws Exception {
H I ©
[Link]("AfterAll");
UEL
}
O
f E LM
@BeforeEach

ch r
void setUp() throws Exception { e
} ©A
[Link]("BeforeEach");

@AfterEach
void tearDown() throws Exception {
[Link]("AfterEach");
}

H & H: Research and Training 29 / 103


Pre/Post test

JUnit

Pour mieux comprendre


Lancer le test JUnit

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 30 / 103


Pre/Post test

JUnit

Pour mieux comprendre


Lancer le test JUnit

H I ©
UEL
O
Le résultat
f E LM
BeforeAll
ch r e
BeforeEach
AfterEach
©A
BeforeEach
AfterEach
AfterAll

H & H: Research and Training 30 / 103


Pre/Post test

JUnit

Comprenons les annotations de méthodes précédentes

@BeforeAll : la méthode annotée sera exécutée seulement


avant le premier test
H I ©
UEL
O
@AfterAll : la méthode annotée sera exécutée seulement après
le dernier test
f E LM
ch r e
@BeforeEach : la méthode annotée sera exécutée avant chaque
test ©A
@AfterEach : la méthode annotée sera exécutée après chaque
test

H & H: Research and Training 31 / 103


Pre/Post test

JUnit

Remarques
H I ©
@BeforeAll était @BeforeClass dans JUnit 4.
UEL
O
f E LM
@AfterAll était @AfterClass dans JUnit 4.

r e
@BeforeEach était @Before dans JUnit 4.
ch
©A
@AfterEach était @After dans JUnit 4.

H & H: Research and Training 32 / 103


Pre/Post test

Utilisons ces méthodes pour restructurer la classe CalculTest


class CalculTest {
Calcul calcul;
@BeforeAll
static void setUpBeforeClass() throws Exception { }
@AfterAll
static void tearDownAfterClass() throws Exception { }
@BeforeEach
void setUp() throws Exception {
H I ©
EL
calcul = new Calcul();
}
@AfterEach
O U
void tearDown() throws Exception {
calcul = null;
f E LM
}
ch r e
©A
@Test
void testSomme() {
// le code précédent sans l’instanciation de calcul
}
@Test
void testDivision() {
// le code précédent sans l’instanciation de calcul
}
}

H & H: Research and Training 33 / 103


Mockito

JUnit

Mock ?
Doublure, objet factice (fake object)

H I ©
permettant de reproduire le comportement d’un objet réel non
implémenté
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 34 / 103


Mockito

JUnit

Mock ?
Doublure, objet factice (fake object)

H I ©
permettant de reproduire le comportement d’un objet réel non
implémenté
UEL
O
f E LM
ch r e
Mockito ?
© A
Framework open-source pour Java
Générateur automatique de doublures
Un seul type de Mock possible et une seule façon de le créer

H & H: Research and Training 34 / 103


Mockito

JUnit

Exemple, supposant qu’on


H I ©
EL
OU
a une interface CalculService ayant une méthode carre()
M
f E LsommeCarre() dans Calcul qui
veut développer une méthode

c r e
utilise la méthodehcarre() de cette interface CalculService
© A

H & H: Research and Training 35 / 103


Mockito

JUnit

L’interface CalculService
package [Link];
H I ©
UEL
public interface CalculService { O
f E LM
public int carre(int x);
ch r e
} ©A

H & H: Research and Training 36 / 103


Mockito

JUnit
La classe Calcul
package [Link];

public class Calcul {


CalculService calculService;

public Calcul(CalculService calculService) {


H I ©
}
[Link] = calculService;
U EL
O
E LM
public int sommeCarre(int x, int y) {
f
ch r e
return somme([Link](x), calculService.
carre(y));

©A
}

public int somme(int x, int y) {


return x + y;
}

public int division(int x, int y) {


if (y == 0)
throw new ArithmeticException();
return x / y;
} and Training
H & H: Research 37 / 103
Mockito

JUnit
Pour tester la classe Calcul dans TestCalcul, il faut commencer par
instancier CalculService
class CalculTest {
Calcul calcul;
CalculService calculService;
H I ©
@BeforeEach
UEL
O
LM
void setUp() throws Exception {

f E
calcul = new Calcul(calculService);
r e
ch
}

@Test ©A
void testSommeCarre() {
assertTrue([Link](2, 3) == 13, "calcul
exact");
}
// + le code precedent

H & H: Research and Training 38 / 103


Mockito

JUnit

En testant, on aura l’erreur suivante

[Link]
at [Link]([Link])

H I ©
at [Link]([Link])

UEL
O
f E LM
ch r e
©A

H & H: Research and Training 39 / 103


Mockito

JUnit

En testant, on aura l’erreur suivante

[Link]
at [Link]([Link])
at [Link]([Link])

H I ©
UEL
O
Explication
f E LM
ch r e
©A
La source de l’erreur est l’appel de la méthode carre(x) qui n’est pas implémenté.

Pour corriger cette erreur, on peut utiliser les STUB.

STUB (les bouchons en français) : code qui renvoie le même résultat pour une méthode
invoquée.

H & H: Research and Training 39 / 103


Mockito

JUnit
Pour tester la classe Calcul dans TestCalcul, il faut commencer par
instancier un objet d’une classe anonyme implémentant CalculService

class CalculTest {
Calcul calcul;

H I ©
CalculService calculService =
EL
new CalculService() {
U
O
LM
@Override
public int carre(int x) {
r e f E
// TODO Auto-generated method stub
ch
©A
return x * x;
}
};

// + le code précédent

H & H: Research and Training 40 / 103


Mockito

JUnit

Ou en utilisant les expressions Lambda


class CalculTest {
H I ©
EL
Calcul calcul;

O U
f E LM
CalculService calculService = (int x) -> x * x;

h r e
// + le code cprécédent
© A
}

H & H: Research and Training 41 / 103


Mockito

JUnit

En testant
tout se passe bien et le test est passé. H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 42 / 103


Mockito

JUnit

En testant
tout se passe bien et le test est passé. H I ©
UEL
O
f E LM
On peut utiliser les mocks ch r e
©A
pour créer un objet factice de CalculService.

H & H: Research and Training 42 / 103


Mockito

JUnit

Démarche
Aller dans
H I ©
EL
[Link] et
télécharger mockito-core
M OU
laL
Créer un répertoire lib àE racine du projet
e f
hr mockito-core et copier les 4 .jar
Décompresserc
dans lib© A l’archive

Ajouter les .jar de lib au path du projet

H & H: Research and Training 43 / 103


Quelques méthodes pour les mocks mock

JUnit

Commençons par importer mockito dans la classe CalculTest

H I ©
EL
import static [Link].*;

O U
f E LM
ch r e
©A

H & H: Research and Training 44 / 103


Quelques méthodes pour les mocks mock

JUnit

Commençons par importer mockito dans la classe CalculTest

H I ©
EL
import static [Link].*;

O U
f E LM
ch r e
Remplaçons l’instanciation de CalculService par un mock
CalculService A
calculService = mock([Link]);
©

H & H: Research and Training 44 / 103


Quelques méthodes pour les mocks when ... thenReturn

JUnit

Utilisons when ... thenReturn pour indiquer ce qu’il faut retourner lorsque
la méthode carre est appelée avec les paramètres 2 ou 3

@Test
H I ©
void testSommeCarre() {
when([Link](2)).thenReturn(4);
U EL
O
LM
when([Link](3)).thenReturn(9);

}
r e E
assertTrue([Link](2, 3) == 13, "calcul exact");
f
ch
©A

H & H: Research and Training 45 / 103


Quelques méthodes pour les mocks when ... thenReturn

JUnit

Utilisons when ... thenReturn pour indiquer ce qu’il faut retourner lorsque
la méthode carre est appelée avec les paramètres 2 ou 3

@Test
H I ©
void testSommeCarre() {
when([Link](2)).thenReturn(4);
U EL
O
LM
when([Link](3)).thenReturn(9);

}
r e E
assertTrue([Link](2, 3) == 13, "calcul exact");
f
ch
©A
Lancez le test et vérifiez qu’il se termine correctement.

H & H: Research and Training 45 / 103


Quelques méthodes pour les mocks doReturn ... when

JUnit

Nous pouvons également utiliser doReturn ... when de la manière suivante

@Test
void testSommeCarre() {
H I ©
when([Link](2)).thenReturn(4);
U EL
doReturn(9).when(calculService).carre(3);
O
}
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");

ch r e
©A

H & H: Research and Training 46 / 103


Quelques méthodes pour les mocks doReturn ... when

JUnit

Nous pouvons également utiliser doReturn ... when de la manière suivante

@Test
void testSommeCarre() {
H I ©
when([Link](2)).thenReturn(4);
U EL
doReturn(9).when(calculService).carre(3);
O
}
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");

ch r e
©A
Lancez le test et vérifiez qu’il se termine correctement.

H & H: Research and Training 46 / 103


Quelques méthodes pour les mocks doReturn ... when

JUnit

Remarques
H I ©
EL
OU
when ... thenReturn n’accepte pas les méthodes void.
M
doReturn accepte toutesE
f Lméthodes quelle que soit la valeur
les
de retour.
chr e
© A

H & H: Research and Training 47 / 103


Quelques méthodes pour les mocks verify

JUnit
Pour vérifier que le mock a bien été appelé, on peut utiliser la méthode verify

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
H I ©
EL
when([Link](4)).thenReturn(16);
assertTrue([Link](2, 3) == 13, "calcul exact");
O U
LM
verify(calculService).carre(2);
}

r e f E
ch
©A

H & H: Research and Training 48 / 103


Quelques méthodes pour les mocks verify

JUnit
Pour vérifier que le mock a bien été appelé, on peut utiliser la méthode verify

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
H I ©
EL
when([Link](4)).thenReturn(16);
assertTrue([Link](2, 3) == 13, "calcul exact");
O U
LM
verify(calculService).carre(2);
}

r e f E
ch
©A
Remarque

Remplacez verify(calculService).carre(2) par


verify(calculService).carre(4) et vérifiez que le test échoue.

H & H: Research and Training 48 / 103


Quelques méthodes pour les mocks verify

JUnit

Et si on n’appelle plus la méthode carre() de CalculService dans Calcul

public int sommeCarre(int x, int y) {


return somme(x * x, y * y);
}
H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 49 / 103


Quelques méthodes pour les mocks verify

JUnit

Et si on n’appelle plus la méthode carre() de CalculService dans Calcul

public int sommeCarre(int x, int y) {


return somme(x * x, y * y);
}
H I ©
UEL
O
Testons de nouveau testSommeCarre()
f E LM
@Test
ch r e
©A
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
assertTrue([Link](2, 3) == 13, "calcul exact");
verify(calculService).carre(2);
}

H & H: Research and Training 49 / 103


Quelques méthodes pour les mocks verify

JUnit

Le résultat est
Wanted but not invoked:
[Link](2);
H I ©
EL
-> at [Link](
[Link])
O U
LM
Actually, there were zero interactions with this mock.

r e f E
ch
©A

H & H: Research and Training 50 / 103


Quelques méthodes pour les mocks verify

JUnit

Le résultat est
Wanted but not invoked:
[Link](2);
H I ©
EL
-> at [Link](
[Link])
O U
LM
Actually, there were zero interactions with this mock.

r e f E
ch
Explication ©A
Tout mock créé doit être invoqué.

H & H: Research and Training 50 / 103


Quelques méthodes pour les mocks times

JUnit

Pour vérifier que carre(2) a été appelé une seule fois, on peut utiliser la
méthode times

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
when([Link](3)).thenReturn(9);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

}
verify(calculService, times(1)).carre(2);

f E LM
ch r e
©A

H & H: Research and Training 51 / 103


Quelques méthodes pour les mocks times

JUnit

Pour vérifier que carre(2) a été appelé une seule fois, on peut utiliser la
méthode times

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
when([Link](3)).thenReturn(9);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

}
verify(calculService, times(1)).carre(2);

f E LM
ch r e
©A
Remarque

Remplacez times(1) par times(2) et vérifiez que le test échoue.

H & H: Research and Training 51 / 103


Quelques méthodes pour les mocks atLeast

JUnit

Pour vérifier que carre(2) a été appelé au moins une fois, on peut utiliser la
méthode atLeast

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
when([Link](3)).thenReturn(9);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

}
verify(calculService, atLeast(1)).carre(2);

f E LM
ch r e
©A

H & H: Research and Training 52 / 103


Quelques méthodes pour les mocks atLeast

JUnit

Pour vérifier que carre(2) a été appelé au moins une fois, on peut utiliser la
méthode atLeast

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
when([Link](3)).thenReturn(9);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

}
verify(calculService, atLeast(1)).carre(2);

f E LM
ch r e
©A
Remarque

Remplacez atLeast(1) par atLeast(2) et vérifiez que le test échoue.

H & H: Research and Training 52 / 103


Quelques méthodes pour les mocks atLeast

JUnit

Autres méthodes similaires

H I ©
atLeastOnce() : au moins une fois .
UEL
O
LM
atMost(n) : au plus n fois.

r e
atMostOnce() : au plus une fois.f E
ch
...
©A

H & H: Research and Training 53 / 103


Quelques méthodes pour les mocks any

JUnit
Pour vérifier que carre a été appelé deux fois avec des paramètres de type
Integer, on peut utiliser la méthode any

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
H I ©
when([Link](4)).thenReturn(16);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

class));
f E LM
verify(calculService, times(2)).carre([Link](Integer.

}
ch r e
©A

H & H: Research and Training 54 / 103


Quelques méthodes pour les mocks any

JUnit
Pour vérifier que carre a été appelé deux fois avec des paramètres de type
Integer, on peut utiliser la méthode any

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
H I ©
when([Link](4)).thenReturn(16);
UEL
O
assertTrue([Link](2, 3) == 13, "calcul exact");

class));
f E LM
verify(calculService, times(2)).carre([Link](Integer.

}
ch r e
©A
Remarque

Remplacez times(2) par times(3) et vérifiez que le test échoue.

H & H: Research and Training 54 / 103


Quelques méthodes pour les mocks anyInt

JUnit
Pour vérifier que carre a été appelé deux fois avec des paramètres de type
Integer, on peut aussi utiliser la méthode anyInt

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
EL
when([Link](3)).thenReturn(9);
when([Link](4)).thenReturn(16);
O U
LM
assertTrue([Link](2, 3) == 13, "calcul exact");

}
r e E
verify(calculService, times(2)).carre([Link]());
f
ch
©A

H & H: Research and Training 55 / 103


Quelques méthodes pour les mocks anyInt

JUnit
Pour vérifier que carre a été appelé deux fois avec des paramètres de type
Integer, on peut aussi utiliser la méthode anyInt

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
EL
when([Link](3)).thenReturn(9);
when([Link](4)).thenReturn(16);
O U
LM
assertTrue([Link](2, 3) == 13, "calcul exact");

}
r e E
verify(calculService, times(2)).carre([Link]());
f
ch
©A
Remarque

Remplacez times(2) par times(3) et vérifiez que le test échoue.

H & H: Research and Training 55 / 103


Quelques méthodes pour les mocks anyInt

JUnit

Autres méthodes similaires


anyByte()
H I ©
anyShort()
UEL
O
anyChar()
f E LM
anyFloat()
ch r e
anyDouble() ©A
...

H & H: Research and Training 56 / 103


Quelques méthodes pour les mocks never

JUnit
Pour vérifier que carre(4) n’a jamais été appelé, on peut utiliser la méthode
never

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
EL
when([Link](3)).thenReturn(9);
assertTrue([Link](2, 3) == 13, "calcul exact");
O U
LM
verify(calculService, never()).carre(4);
}

r e f E
ch
©A

H & H: Research and Training 57 / 103


Quelques méthodes pour les mocks never

JUnit
Pour vérifier que carre(4) n’a jamais été appelé, on peut utiliser la méthode
never

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
H I ©
EL
when([Link](3)).thenReturn(9);
assertTrue([Link](2, 3) == 13, "calcul exact");
O U
LM
verify(calculService, never()).carre(4);
}

r e f E
ch
©A
Remarque

Remplacez verify(calculService, never()).carre(4) par


verify(calculService, never()).carre(2) et vérifiez que le test échoue.

H & H: Research and Training 57 / 103


Quelques méthodes pour les mocks only

JUnit

Pour vérifier si carre() a été appelé une seule fois quel que soit le nombre de
paramètres, on peut utiliser la méthode only

H I ©
EL
@Test
void testSommeCarre() {
O U
LM
when([Link](2)).thenReturn(4);

r e E
when([Link](3)).thenReturn(9);
f
assertTrue([Link](2, 3) == 13, "calcul exact");
ch
©A
verify(calculService, only()).carre(4);
}

H & H: Research and Training 58 / 103


Quelques méthodes pour les mocks inOrder

JUnit
Pour vérifier l’ordre d’interactions avec le mock, on peut utiliser la méthode inOrder

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
assertTrue([Link](2, 3) == 13, "calcul exact");
H I ©
InOrder ordre = [Link](calculService);
[Link](calculService).carre(2);
UEL
O
LM
[Link](calculService).carre(3);
}

r e f E
ch
©A

H & H: Research and Training 59 / 103


Quelques méthodes pour les mocks inOrder

JUnit
Pour vérifier l’ordre d’interactions avec le mock, on peut utiliser la méthode inOrder

@Test
void testSommeCarre() {
when([Link](2)).thenReturn(4);
when([Link](3)).thenReturn(9);
assertTrue([Link](2, 3) == 13, "calcul exact");
H I ©
InOrder ordre = [Link](calculService);
[Link](calculService).carre(2);
UEL
O
LM
[Link](calculService).carre(3);
}

r e f E
ch
©A
Remarque

Inverser [Link](calculService).carre(2) par


[Link](calculService).carre(3) et vérifiez que le test échoue.

H & H: Research and Training 59 / 103


Quelques méthodes pour les mocks when ... thenAnswer

JUnit

Utilisons when ... thenAnswer pour définir le comportement de la méthode simulée


tout en pouvant récupérer les paramètres et retourner un résultat

@Test
void testSommeCarre() {
when([Link]([Link]())).thenAnswer(
H I ©
(invocation) -> {
U EL
Integer entier = [Link](0);
O
LM
return entier * entier;
});

r e f E
assertTrue([Link](2, 3) == 13, "calcul exact");
}
ch
©A

H & H: Research and Training 60 / 103


Quelques méthodes pour les mocks when ... thenAnswer

JUnit

Utilisons when ... thenAnswer pour définir le comportement de la méthode simulée


tout en pouvant récupérer les paramètres et retourner un résultat

@Test
void testSommeCarre() {
when([Link]([Link]())).thenAnswer(
H I ©
(invocation) -> {
U EL
Integer entier = [Link](0);
O
LM
return entier * entier;
});

r e f E
assertTrue([Link](2, 3) == 13, "calcul exact");
}
ch
©A
Lancez le test et vérifiez qu’il se termine correctement.

H & H: Research and Training 60 / 103


Quelques méthodes pour les mocks doAnswer ... when

JUnit

Nous pouvons également utiliser doAnswer ... when de la manière suivante

@Test
void testSommeCarre() {
doAnswer((invocation) -> {
H I ©
Integer entier = [Link](0);
U EL
return entier * entier;
O
}).when(calculService).carre([Link]());
f E LM
}
ch r e
assertTrue([Link](2, 3) == 13, "calcul exact");

©A

H & H: Research and Training 61 / 103


Quelques méthodes pour les mocks doAnswer ... when

JUnit

Nous pouvons également utiliser doAnswer ... when de la manière suivante

@Test
void testSommeCarre() {
doAnswer((invocation) -> {
H I ©
Integer entier = [Link](0);
U EL
return entier * entier;
O
}).when(calculService).carre([Link]());
f E LM
}
ch r e
assertTrue([Link](2, 3) == 13, "calcul exact");

©A
Lancez le test et vérifiez qu’il se termine correctement.

H & H: Research and Training 61 / 103


Quelques méthodes pour les mocks doAnswer ... when

JUnit

Remarques
H I ©
EL
OU
when ... thenAnswer n’accepte pas les méthodes void.
M
doAnswer accepte toutesE
f Lméthodes quelle que soit la valeur
les
de retour.
chr e
© A

H & H: Research and Training 62 / 103


Quelques méthodes pour les mocks when ... thenThrow

JUnit

Remarques
H I ©
Un mock est initialement introduit pour simuler des objets U EL
O
f E LM
externes ou non instanciables (interface, classe abstraite...)

ch r e
Mais il peut aussi simuler le comportement d’une classe concrète.

©A

H & H: Research and Training 63 / 103


Quelques méthodes pour les mocks when ... thenThrow

Considérons la classe Point suivante

public class Point {


private double abs;
private double ord;

public Point(double abs, double ord) {


[Link] = abs;
[Link] = ord;
}
H I ©
public Point deplacerOrd(double d) {
U EL
O
LM
ord += d;
return this;
}
r e f E
ch
©A
public void deplacerAbs(double d) {
abs += d;
}

public final void deplacer(double d) {


abs += d;
ord += d;
}
}

H & H: Research and Training 64 / 103


Quelques méthodes pour les mocks when ... thenThrow
Pour tester la classe Point, commençons par créer la classe PointTest et préparer le mock

@RunWith([Link])
class PointTest {
Point pointMock = [Link]([Link]);

@BeforeAll
static void setUpBeforeClass() throws Exception {
}

@AfterAll

©
static void tearDownAfterClass() throws Exception {
}

H I
@BeforeEach
void setUp() throws Exception {
U EL
}
O
@AfterEach

f E LM
}

ch r e
void tearDown() throws Exception {

©A
@Test
void testDeplacerOrd() {
}

@Test
void testDeplacerAbs() {
}

@Test
void testDeplacer() {
}
}

H & H: Research and Training 65 / 103


Quelques méthodes pour les mocks when ... thenThrow

JUnit

Utilisons when ... thenThrow pour lever une exception si certains paramètres sont
présents

@Test
void testDeplacerOrd() {
H I ©
when([Link](Double.MAX_VALUE))
U EL
O
LM
.thenThrow([Link]);
Throwable e = null;
try {
r e f E
ch
[Link](Double.MAX_VALUE);

©A
} catch (Exception ex) {
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 66 / 103


Quelques méthodes pour les mocks when ... thenThrow

JUnit
Ajoutons l’affichage suivant dans la méthode deplacerOrd

public Point deplacerOrd(double d) {


[Link](d);
ord += d;

}
return this;
H I ©
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 67 / 103


Quelques méthodes pour les mocks when ... thenThrow

JUnit
Ajoutons l’affichage suivant dans la méthode deplacerOrd

public Point deplacerOrd(double d) {


[Link](d);
ord += d;

}
return this;
H I ©
U EL
O
f E LM
Remarques
ch r e
©A
En lançant le test, le message ajouté ne s’affiche pas.

En effet, appeler une méthode après un when permet de retourner le résultat


indiqué par thenReturn ou thenThrow.

Le mock renvoie null si la méthode appelée n’est pas définie avec un when.

H & H: Research and Training 67 / 103


Quelques méthodes pour les mocks doThrow ... when

JUnit

Remarques H I ©
U EL
O
when ... thenThrow n’accepte pas les méthodes void.
Mais on peut utiliser doThrow. f E LM
ch r e
©A

H & H: Research and Training 68 / 103


Quelques méthodes pour les mocks doThrow ... when

JUnit

Utilisons doThrow pour lever une exception si certains paramètres sont présents pour
tester la méthode déplacerAbs ne retournant pas de valeurs

@Test
void testDeplacerAbs() {
H I ©
doThrow([Link]).when(pointMock).deplacerAbs(
Double.MAX_VALUE);
U EL
O
LM
Throwable e = null;
try {

e f E
[Link](Double.MAX_VALUE);
r
} catch (Exception ex) {
ch
©A
e = ex;
}
assertTrue(e instanceof ArithmeticException);
}

H & H: Research and Training 69 / 103


Quelques méthodes pour les mocks spy

JUnit

Remarques

Un mock ne peut jamais simuler une méthode finale.


H I ©
EL
Il ne peut utiliser la version définie dans la classe réelle car il
U
O
retourne null si la méthode n’est pas mentionnée dans un when.

f E LM
ch r e
©A

H & H: Research and Training 70 / 103


Quelques méthodes pour les mocks spy

JUnit

Remarques

Un mock ne peut jamais simuler une méthode finale.


H I ©
EL
Il ne peut utiliser la version définie dans la classe réelle car il
U
O
retourne null si la méthode n’est pas mentionnée dans un when.

f E LM
ch r e
Solution
©A
Utiliser les espions (Spy).

H & H: Research and Training 70 / 103


Quelques méthodes pour les mocks spy

JUnit

Spy ?

I
Un spy est un mock partiel créé à partir d’une instance réelle.
H ©
UEL
O
Une partie de l’objet sera simulée et une partie utilisera des
invocations de méthodes réelles.
f E LM
ch r e
Si un spy appelle une méthode non mentionnée dans un when,
©A
c’est la méthode originale définie dans la classe réelle qui sera
appelée.

H & H: Research and Training 71 / 103


Quelques méthodes pour les mocks spy

JUnit

Remplaçons la déclaration du mock


Point pointMock = mock([Link]);

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 72 / 103


Quelques méthodes pour les mocks spy

JUnit

Remplaçons la déclaration du mock


Point pointMock = mock([Link]);

H I ©
EL
OU
Par celle d’un spy construit à partir d’une instance réelle
M
f E L
Point pointMock = [Link](new Point(2, 2));
ch r e
© A

H & H: Research and Training 72 / 103


Quelques méthodes pour les mocks spy

JUnit

Remplaçons la déclaration du mock


Point pointMock = mock([Link]);

H I ©
EL
OU
Par celle d’un spy construit à partir d’une instance réelle
M
f E L
Point pointMock = [Link](new Point(2, 2));
ch r e
© A
Vérifiez que les tests précédents passent toujours.

H & H: Research and Training 72 / 103


Quelques méthodes pour les mocks spy

Définissons le test de la méthode finale

@Test
void testDeplacer() {
Point resultat = new Point(6.0, 6.0);
assertTrue([Link]([Link](4)));
}

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 73 / 103


Quelques méthodes pour les mocks spy

Définissons le test de la méthode finale

@Test
void testDeplacer() {
Point resultat = new Point(6.0, 6.0);
assertTrue([Link]([Link](4)));
}

H I ©
UEL
Et redéfinissons la méthode equals dans Point
O
@Override
f E LM
public boolean equals(Object obj) {
Point p = (Point) obj;
ch r e
©A
return [Link] == abs && [Link] == ord;
}

H & H: Research and Training 73 / 103


Quelques méthodes pour les mocks spy

Définissons le test de la méthode finale

@Test
void testDeplacer() {
Point resultat = new Point(6.0, 6.0);
assertTrue([Link]([Link](4)));
}

H I ©
UEL
Et redéfinissons la méthode equals dans Point
O
@Override
f E LM
public boolean equals(Object obj) {
Point p = (Point) obj;
ch r e
©A
return [Link] == abs && [Link] == ord;
}

Vérifiez que le test passe correctement.

H & H: Research and Training 73 / 103


Quelques méthodes pour les mocks spy

JUnit

Remarques
Pour les spy, when ... thenReturn et when ... H I ©
UEL
thenThrow appellent la méthode de la classe réelle juste avant
O
f E LM
que la valeur spécifiée ne soit renvoyée. Donc, si la méthode
appelée lève une exception, il faut la gérer / la simuler, etc.
r e
ch n’appelle pas du tout la méthode de la
doReturn et
classe r©
A
éelle.
doThrow

H & H: Research and Training 74 / 103


Capture d’arguments

JUnit

Reprenons la méthode testSommeCarre()

@Test
void testSommeCarre() {
doAnswer((invocation) -> {
Integer entier = [Link](0);
H I ©
return entier * entier;
UEL
}).when(calculService).carre([Link]());
O
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");
}

ch r e
©A

H & H: Research and Training 75 / 103


Capture d’arguments

JUnit

Reprenons la méthode testSommeCarre()

@Test
void testSommeCarre() {
doAnswer((invocation) -> {
Integer entier = [Link](0);
H I ©
return entier * entier;
UEL
}).when(calculService).carre([Link]());
O
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");
}

ch r e
©A
Question

Comment capturer les arguments utilisées dans une méthode simulée ?

H & H: Research and Training 75 / 103


Capture d’arguments

JUnit

Réponse
Utiliser ArgumentCaptor

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 76 / 103


Capture d’arguments

JUnit

Réponse
Utiliser ArgumentCaptor

H I ©
UEL
O
ArgumentCaptor ?
f E LM
r e
h verify pour capturer les paramètres
passés © Amcéthode
utilisé avec la m
à une
éthode
simulée.
particulièrement utile lorsque nous ne pouvons pas accéder à un
paramètre en dehors de la méthode simulée.

H & H: Research and Training 76 / 103


Capture d’arguments

JUnit

Exemple

@Test
void testSommeCarre() {
ArgumentCaptor<Integer> nbr = [Link]([Link]);
doAnswer((invocation) -> {
H I ©
EL
Integer entier = [Link](0);
return entier * entier;
}).when(calculService).carre([Link]());
O U
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");
verify(calculService, times(2)).carre([Link]());

r e
assertEquals(2, [Link]().get(0));
ch
©A
assertEquals(3, [Link]().get(1));
}

H & H: Research and Training 77 / 103


Capture d’arguments

JUnit

Exemple

@Test
void testSommeCarre() {
ArgumentCaptor<Integer> nbr = [Link]([Link]);
doAnswer((invocation) -> {
H I ©
EL
Integer entier = [Link](0);
return entier * entier;
}).when(calculService).carre([Link]());
O U
f E LM
assertTrue([Link](2, 3) == 13, "calcul exact");
verify(calculService, times(2)).carre([Link]());

r e
assertEquals(2, [Link]().get(0));
ch
©A
assertEquals(3, [Link]().get(1));
}

Lancez le test et vérifiez qu’il se termine correctement.

H & H: Research and Training 77 / 103


Capture d’arguments

JUnit

Explication

ArgumentCaptor<Integer> nbr =
[Link]([Link]) permet de déclarer un capteur
d’argument de type Integer.

H I ©
EL
[Link]() permet de capturer les arguments de type entier.

O U
[Link]() retourne les arguments capturés de type entier.

f E LM
ch r e
©A

H & H: Research and Training 78 / 103


Capture d’arguments

JUnit

Explication

ArgumentCaptor<Integer> nbr =
[Link]([Link]) permet de déclarer un capteur
d’argument de type Integer.

H I ©
EL
[Link]() permet de capturer les arguments de type entier.

O U
[Link]() retourne les arguments capturés de type entier.

f E LM
ch r e
Remarques ©A
Si une méthode prend plusieurs arguments de types différents, alors il faut déclarer un
capteur d’arguments par type.

Si le capteur capture une seule valeur, on peut utiliser [Link]().

H & H: Research and Training 78 / 103


Quelques annotations pour les mocks @Mock

JUnit

On peut aussi utiliser les annotations pour créer un mock


@Mock
CalculService calculService;

H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 79 / 103


Quelques annotations pour les mocks @Mock

JUnit

On peut aussi utiliser les annotations pour créer un mock


@Mock
CalculService calculService;

H I ©
UEL
O
Remarques
f E LM
r e
ch @Mock, il faut soit :
Pour activer l’annotation
A
appeler© la méthode initMocks (ou openMocks depuis Mockito
3).
annoter la classe de test par @ExtendWith.

H & H: Research and Training 79 / 103


Quelques annotations pour les mocks @Mock

JUnit
Activons l’annotation @Mock (Pour Mockito 2, remplacez openMocks par
initMocks)
class CalculTest {

Calcul calcul;
H I ©
UEL
@Mock
O
CalculService calculService;
f E LM
@BeforeEach
ch r e
©A
void setUp() throws Exception {
[Link](this);
calcul = new Calcul(calculService);
}

// + le code précédent

H & H: Research and Training 80 / 103


Quelques annotations pour les mocks @ExtendWith

JUnit
On peut aussi remplacer l’appel de la méthode openMocks par
l’annotation @ExtendWith([Link])
@ExtendWith([Link])
class CalculTest {

H I ©
Calcul calcul;
U EL
O
@Mock
f E LM
CalculService calculService;
ch r e
@BeforeEach
©A
void setUp() throws Exception {
calcul = new Calcul(calculService);
}

// + le code précédent

H & H: Research and Training 81 / 103


Quelques annotations pour les mocks @InjectMocks

JUnit
On peut aussi automatiser l’injection du mock dans le constructeur de
la classe Calcul en utilisant l’annotation @InjectMocks
@ExtendWith([Link])
class CalculTest {

H I ©
@Mock
U EL
CalculService calculService;
O
f E LM
@InjectMocks
Calcul calcul;
ch r e
@BeforeEach ©A
void setUp() throws Exception {
}

// + le code précédent

H & H: Research and Training 82 / 103


Quelques annotations pour les mocks @Spy

On peut aussi remplacer l’appel de la méthode spy par l’annotation @Spy

@ExtendWith([Link])
class PointTest {

@Spy
Point pointMock = new Point(2, 2);

@BeforeAll
static void setUpBeforeClass() throws Exception {
H I ©
EL
}

O U
LM
@AfterAll
static void tearDownAfterClass() throws Exception {
}
r e f E
ch
©A
@BeforeEach
void setUp() throws Exception {
}

@AfterEach
void tearDown() throws Exception {
}

// + les tests

H & H: Research and Training 83 / 103


Quelques annotations pour les mocks @Captor

JUnit
On peut aussi déclarer le capteur avec @Captor

@ExtendWith([Link])
class CalculTest {

@Mock
CalculService calculService;

@InjectMocks
Calcul calcul;

H I ©
@Captor
ArgumentCaptor<Integer> nbr;
UEL
O
LM
@BeforeEach
void setUp() throws Exception {
}

r e f E
@Test
ch
©A
void testSommeCarre() {
doAnswer((invocation) -> {
Integer entier = [Link](0);
return entier * entier;
}).when(calculService).carre([Link]());
assertTrue([Link](2, 3) == 13, "calcul exact");
verify(calculService, times(2)).carre([Link]());
assertEquals(2, [Link]().get(0));
assertEquals(3, [Link]().get(1));
}

// + les autres tests

H & H: Research and Training 84 / 103


JUnit et Maven

JUnit

Commençons par créer un Java Project avec Maven


Aller dans File > New > Other
Chercher puis sélectionner Maven Project
H I ©
EL
Cliquer sur Next
M OU
f E L
Choisir maven-archetype-quickstart
chr e
A
Remplir les champs
©
Group Id avec [Link]
Artifact Id avec cours-junit-maven
Package avec [Link]

H & H: Research and Training 85 / 103


JUnit et Maven

JUnit
Vérifier l’existence des deux répertoires

/src/main/java : code source

/src/test/java : code source de test

...
H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 86 / 103


JUnit et Maven

JUnit
Vérifier l’existence des deux répertoires

/src/main/java : code source

/src/test/java : code source de test

...
H I ©
UEL
O
f E
S’il n’y a pas de src/main/java ou src/test/java LM
ch r e
©A
Faire clic droit sur le projet

Aller dans Build Path > Configure Build Path...

Cliquer sur Order and Export

Cocher les cases Maven Dependencies et JRE System Library

Cliquer sur Apply and Close

H & H: Research and Training 86 / 103


JUnit et Maven

JUnit

H I ©
Ajouter les propriétés suivantes dans la section properties de [Link]

<properties>
U EL
<[Link]>UTF-8</[Link]>
O
LM
<[Link]>5.7.0</[Link]>

e E
<[Link]>1.7.0</[Link]>
f
<[Link]>3.7.7</[Link]>
r
</properties>
ch
©A

H & H: Research and Training 87 / 103


JUnit et Maven

JUnit
Ajouter les dépendances suivantes dans la section dependencies de [Link]

<dependency>
<groupId>[Link]</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${[Link]}</version>
<scope>test</scope>
H I ©
EL
</dependency>

<dependency>
O U
<groupId>[Link]</groupId>

f E LM
<artifactId>junit-jupiter</artifactId>

r e
<version>${[Link]}</version>
ch
©A
<scope>test</scope>
</dependency>

dependency>
<groupId>[Link]</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${[Link]}</version>
<scope>test</scope>
</dependency>

H & H: Research and Training 88 / 103


Quelques annotations pour les tests @RunWith

JUnit

Pour tester
Déplacez le package [Link] du projet précédent
H I ©
dans src/main/java.
UEL
O
Déplacez le package [Link] dans
f E LM
ch r e
src/test/java et renommez le [Link].

©A
Annotez les classes de test par
@RunWith([Link]).

H & H: Research and Training 89 / 103


Quelques annotations pour les tests @RunWith

JUnit
Ajoutez l’annotation @RunWith([Link]) à la
classe CalculTest puis lancez le test
package [Link];

H I ©
EL
import [Link];

OU
import [Link];

L M
f E
// + les imports précédents
e
A chr
©
@ExtendWith([Link])
@RunWith([Link])
class CalculTest {

// + le code précédent

H & H: Research and Training 90 / 103


Quelques annotations pour les tests @DisplayName

JUnit

Pour modifier l’affichage de la classe de test, on utilise @DisplayName


package [Link];

import [Link];
H I ©
U EL
O
LM
// + les imports précédents

r e f
@DisplayName("Test de la classe Calcul") E
ch
©A
@ExtendWith([Link])
@RunWith([Link])
class CalculTest {
// + tout le code précédent

H & H: Research and Training 91 / 103


Quelques annotations pour les tests @DisplayName

JUnit

@DisplayName peut être utilisée aussi avec les méthodes


H I ©
@Test
U EL
@DisplayName("Test de la méthode sommeCarre")
O
void testSommeCarre() {
f E LM
}
...
ch r e
©A

H & H: Research and Training 92 / 103


Quelques annotations pour les tests @Disabled

JUnit

Pour désactiver un test, on utilise l’annotation @Disabled (ou


@Ignore dans JUnit 4)
H I ©
@Disabled
U EL
O
@Test
void testSomme() {
f E LM
...
ch r e
}
©A

H & H: Research and Training 93 / 103


Quelques annotations pour les tests @RepeatedTest

JUnit
Utiliser @RepeatedTest pour répéter un test plusieurs fois
@RepeatedTest(3)
void testSomme(RepetitionInfo repetitionInfo) {
assertNotEquals(7, [Link](repetitionInfo.
H I ©
EL
getCurrentRepetition(),3));
}
O U
f E LM
ch r e
©A

H & H: Research and Training 94 / 103


Quelques annotations pour les tests @RepeatedTest

JUnit
Utiliser @RepeatedTest pour répéter un test plusieurs fois
@RepeatedTest(3)
void testSomme(RepetitionInfo repetitionInfo) {
assertNotEquals(7, [Link](repetitionInfo.
H I ©
EL
getCurrentRepetition(),3));
}
O U
f E LM
ch r e
Explication ©A
Il faut remplacer @Test par @RepeatedTest.
Pour récupérer l’index de l’itération courante, on déclare un objet
de type RepetitionInfo.

H & H: Research and Training 94 / 103


Quelques annotations pour les tests @RepeatedTest

JUnit

On peut utiliser @RepeatedTest pour personnaliser le message afficher


H I ©
@RepeatedTest(value = 3, name = RepeatedTest.LONG_DISPLAY_NAME)
U EL
void testSomme(RepetitionInfo repetitionInfo) {
O
assertNotEquals(7, [Link](repetitionInfo.
getCurrentRepetition(), 3));
f E LM
}
ch r e
©A

H & H: Research and Training 95 / 103


Quelques annotations pour les tests @ParameterizedTest

JUnit
Utiliser @ParameterizedTest pour paramétrer un test

@DisplayName("Test de la methode somme")


@ParameterizedTest
@ValueSource(ints = { 2, 3 })
void testSomme(int t) {
assertNotEquals(5, [Link](t, 1));
H I ©
EL
}

O U
f E LM
ch r e
©A

H & H: Research and Training 96 / 103


Quelques annotations pour les tests @ParameterizedTest

JUnit
Utiliser @ParameterizedTest pour paramétrer un test

@DisplayName("Test de la methode somme")


@ParameterizedTest
@ValueSource(ints = { 2, 3 })
void testSomme(int t) {
assertNotEquals(5, [Link](t, 1));
H I ©
EL
}

O U
f E LM
Explication
ch r e
©A
Il faut remplacer @Test par @ParameterizedTest.

Cette méthode sera testée deux fois : une fois pour la valeur 2 et une fois pour la valeur 3.

@ValueSource indique les valeurs à injecter dans t à chaque appel.

Il existe aussi strings, longs et doubles.

H & H: Research and Training 96 / 103


Quelques annotations pour les tests @ParameterizedTest

JUnit

Pour utiliser l’annotation @ParameterizedTest, il faut ajouter la


dépendance suivante :
H I ©
<dependency>
U EL
<groupId>[Link]</groupId> O
E
<artifactId>junit-jupiter-params</artifactId>
f LM
ch r e
<version>${[Link]}</version>

©A
<scope>test</scope>
</dependency>

H & H: Research and Training 97 / 103


Quelques annotations pour les tests @ParameterizedTest

JUnit

Annotations à utiliser avec @ParameterizedTest


@ValueSource
H I ©
@EnumSource U EL
O
@CsvFileSource
f E LM
ch r e
A
@MethodSource
©
...

H & H: Research and Training 98 / 103


Quelques annotations pour les tests @DisabledOnOs et @EnabledOnOs

JUnit
Pour activer ou désactiver un test selon le système d’exploitation, on
utilise soit @DisabledOnOs soit @EnabledOnOs
@Test
@DisabledOnOs(MAC)
void testSommeCarre() {
H I ©
EL
...
}
O U
f E LM
ch r e
©A

H & H: Research and Training 99 / 103


Quelques annotations pour les tests @DisabledOnOs et @EnabledOnOs

JUnit
Pour activer ou désactiver un test selon le système d’exploitation, on
utilise soit @DisabledOnOs soit @EnabledOnOs
@Test
@DisabledOnOs(MAC)
void testSommeCarre() {
H I ©
EL
...
}
O U
f E LM
r
ch MAC e
Il faut importer la constante
import static
A
© [Link];

H & H: Research and Training 99 / 103


Quelques annotations pour les tests @DisabledOnOs et @EnabledOnOs

JUnit
Pour activer ou désactiver un test selon le système d’exploitation, on
utilise soit @DisabledOnOs soit @EnabledOnOs
@Test
@DisabledOnOs(MAC)
void testSommeCarre() {
H I ©
EL
...
}
O U
f E LM
r
ch MAC e
Il faut importer la constante
import static
A
© [Link];

Autres constantes possibles : LINUX, WINDOWS

H & H: Research and Training 99 / 103


Quelques annotations pour les tests @DisabledOnJre et @EnabledOnJre

JUnit
Pour activer ou désactiver un test selon la version de JRE, on utilise soit
@DisabledOnJre soit @EnabledOnJre

@Test
@DisabledOnOs(MAC)
@EnabledOnJre(JAVA_10)
void testSommeCarre() {
H I ©
...
U EL
}
O
f E LM
ch r e
©A

H & H: Research and Training 100 / 103


Quelques annotations pour les tests @DisabledOnJre et @EnabledOnJre

JUnit
Pour activer ou désactiver un test selon la version de JRE, on utilise soit
@DisabledOnJre soit @EnabledOnJre

@Test
@DisabledOnOs(MAC)
@EnabledOnJre(JAVA_10)
void testSommeCarre() {
H I ©
...
U EL
}
O
f E LM
r e
ch JAVA 10
A
Il faut importer la constante
©
import static [Link].JAVA_10;

H & H: Research and Training 100 / 103


Quelques annotations pour les tests @DisabledOnJre et @EnabledOnJre

JUnit
Pour activer ou désactiver un test selon la version de JRE, on utilise soit
@DisabledOnJre soit @EnabledOnJre

@Test
@DisabledOnOs(MAC)
@EnabledOnJre(JAVA_10)
void testSommeCarre() {
H I ©
...
U EL
}
O
f E LM
r e
ch JAVA 10
A
Il faut importer la constante
©
import static [Link].JAVA_10;

Autres constantes possibles : JAVA 8, JAVA 9

H & H: Research and Training 100 / 103


Quelques annotations pour les tests @DisabledIf et @EnabledIf

JUnit

Pour activer ou désactiver un test selon la valeur d’un test logique (on peut
même utiliser une expression régulière), on utilise soit @DisabledIf soit
@EnabledIf
H I ©
U EL
@Test
O
@DisabledOnOs(MAC)
@DisabledIf("2 * 3 > 4")
f E LM
void testSommeCarre() {
ch r e
©A
...
}

H & H: Research and Training 101 / 103


Recouvrement du code

JUnit

Objectif

On veut vérifier si nos tests couvrent l’intégralité de notre code.

Ou s’il y a des zones inaccessibles dans notre code.

H I ©
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 102 / 103


Recouvrement du code

JUnit

Objectif

On veut vérifier si nos tests couvrent l’intégralité de notre code.

Ou s’il y a des zones inaccessibles dans notre code.

H I ©
U EL
O
f E LM
Pour cela, il faut installer un plugin Eclipse EclEmma
.
ch r e
©A
Aller dans Help > Install New Software > Add.

Saisir EclEmma dans Name et [Link] dans Location.

Cocher la case EclEmma et cliquer sur Next.

Terminer l’installation et redémarrer Eclipse.

H & H: Research and Training 102 / 103


Recouvrement du code

JUnit

Pour tester le recouvrement du code


Aller dans Window > Show View > Other .... H I ©
UEL
Saisir Coverage et valider. O
f E LM
Aller dans Run.
ch r e
©A
Cliquer sur Coverage et vérifier si votre code est bien couvert par
les tests.

H & H: Research and Training 103 / 103

Vous aimerez peut-être aussi