Temps estimé: 60 minutes
Exercices : Doubler à bras
Maintenant que vous savez ce que c'est qu'un mock, nous allons en créer un manuellement ensemble!
Voici les étapes à suivre:
Préparation
1. Créer un nouveau projet
Ouvrez votre IDE de préférence et créez un nouveau projet Java Maven avec JDK 8 ou une version plus récente. Assurez-vous également d'importer une version récente de JUnit dans la liste des dépendances Maven.
pom.xml:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
2. Ajouter le code
Pour l'exercice, nous avons un téléphone qui permet le "swipe" vers la droite sur une application de rencontre en ligne. Pour vous aider, on vous donne le code suivant:
DatingApp.java:
public class DatingApp {
public void swipeRight() {
System.out.print("Hello there.");
}
}
Phone.java:
public class Phone {
private final DatingApp datingApp;
public void swipeRight() {
datingApp.swipeRight();
}
}
DatingAppTest.java:
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DatingAppTest {
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
@BeforeEach
public void setup() {
System.setOut(new PrintStream(outputStream));
}
@Test
public void whenSwipingRight_thenSayHello() {
DatingApp datingApp = new DatingApp();
datingApp.swipeRight();
assertEquals("Hello there.", outputStream.toString());
}
}
Exercice
1. Tester le comportement du téléphone
Pour vous aider à bien comprendre le fonctionnement d'un mock, nous allons en fabriquer un "à bras", c'est-à-dire sans utiliser de librairies externes.
Pour ce faire, créez la classe de test PhoneTest.java
avec le ou les tests nécessaires tout en respectant les critères d'acceptation suivants:
- S'assurer que tous les comportements du téléphone soient testés.
- Modifier seulement les classes
PhoneTest.java
etPhone.java
. - Importer aucune librairie externe autre que JUnit.
Conseil: Vous allez vite vous rendre compte qu'il est nécessaire d'injecter les dépendances dans Phone.java
.
Phone.java:
public class Phone {
private final DatingApp datingApp;
// L'ajout du mock nécessite l'injection du `DatingApp` dans le constructeur de la clase `Phone`.
public Phone(DatingApp datingApp) {
this.datingApp = datingApp;
}
public void swipeRight() {
datingApp.swipeRight();
}
}
PhoneTest.java:
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class PhoneTest {
@Test
public void whenSwipingRight_thenDatingAppIsSwipedRight() {
DatingAppMock datingApp = new DatingAppMock();
Phone phone = new Phone(datingApp);
phone.swipeRight();
assertTrue(datingApp.swipeRightCalled);
}
private class DatingAppMock extends DatingApp {
public boolean swipeRightCalled = false;
@Override
public void swipeRight() {
this.swipeRightCalled = true;
}
}
}
2. Ajouter la méthode "canSwipeLeft"
Faire maintenant le même exercice, mais avec la méthode swipeLeft
qui doit être ajoutée dans la classe Phone
.
Phone.java:
public String swipeLeft() throws Exception {
if (!datingApp.canSwipeLeft()) {
throw new Exception("User no swiping!");
}
return "General Kenobi";
}
Respectez les critères d'acceptation suivants:
- La méthode
canSwipeLeft
retourne unboolean
:true
si le "swipe" à droite a été effectué au moins une fois,false
sinon (on peut aller à gauche uniquement si on a été à droite avant). - Tous les nouveaux comportements ajoutés doivent être testés.
- Ne pas modifier le code de la classe
Phone
.
DatingApp.java:
public class DatingApp {
private boolean hasSwipedRight = false;
public void swipeRight() {
hasSwipedRight = true;
}
public boolean canSwipeLeft() {
return this.hasSwipedRight;
}
}
PhoneTest.java:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class PhoneTest {
private DatingAppMock datingAppMock;
private Phone phone;
@BeforeEach
public void setup() {
datingAppMock = new DatingAppMock();
phone = new Phone(datingApp);
}
@Test
public void whenSwipingRight_thenDatingAppIsSwipedRight() {
phone.swipeRight();
assertTrue(datingAppMock.swipeRightCalled);
}
@Test
public void givenADatingAppThatCannotSwipeLeft_whenSwipingLeft_thenPreventSwipingLeft() {
datingAppMock.givenCannotSwipeLeft();
assertThrows(Exception.class, () -> phone.swipeLeft());
}
@Test
public void givenADatingAppThatCanSwipeLeft_whenSwipingLeft_thenSayGeneralKenobi() throws Exception {
datingAppMock.givenCanSwipeLeft();
String answer = phone.swipeLeft();
String expectedAnwser = "General Kenobi"; // Constantes? (voir plus tard dans le cours)
assertEquals(expectedAnwser, answer);
}
private class DatingAppMock extends DatingApp {
private boolean canSwipeLeft = false;
public boolean swipeRightCalled = false;
public void givenCanSwipeLeft() {
this.canSwipeLeft = true;
}
public void givenCannotSwipeLeft() {
this.canSwipeLeft = false;
}
@Override
public void swipeRight() {
this.swipeRightCalled = true;
}
@Override
public boolean canSwipeLeft() {
return canSwipeLeft;
}
}
}
DatingAppTest.java:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class DatingAppTest {
private DatingApp datingApp;
@BeforeEach
public void setup() {
datingApp = new DatingApp();
}
@Test
public void givenNeverSwipedRight_whenCheckingIfSwipingLeftIsPossible_thenSwipingLeftIsNotPossible() {
assertFalse(datingApp.canSwipeLeft());
}
@Test
public void givenAlreadySwipedRight_whenCheckingIfSwipingLeftIsPossible_thenSwipingLeftIsPossible() {
datingApp.swipeRight();
assertTrue(datingApp.canSwipeLeft());
}
}
Notez que la réponse obtenu d'un mock peut être très importante lorsqu'elle impacte la classe testée, comme c'est le cas avec Phone
et la méthode mockée canSwipeLeft
.