Exercices pratiques TODO separer les exercices par chapitre
Objectifs du chapitre :
- Mettre en pratique les concepts appris dans les chapitres précédents.
- Renforcer les compétences en écriture et en exécution de tests unitaires avec JUnit.
- Fournir des exemples et des exercices pour chaque module du cours.
19.1 Exercices pour l'Introduction à JUnit
Exercice 1 : Configuration de JUnit dans un projet Maven
- Créez un nouveau projet Maven.
- Ajoutez la dépendance JUnit 5 dans le fichier
pom.xml. - Écrivez un test simple pour vérifier que
1 + 1 = 2. - Exécutez le test et assurez-vous qu'il passe.
Solution :
<!-- pom.xml -->
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
</dependencies>
// CalculatorTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class CalculatorTest {
@Test
public void testAddition() {
assertEquals(2, 1 + 1);
}
}
Exercice 2 : Configuration de JUnit dans un projet Gradle
- Créez un nouveau projet Gradle.
- Ajoutez la dépendance JUnit 5 dans le fichier
build.gradle. - Écrivez un test simple pour vérifier que
2 * 3 = 6. - Exécutez le test et assurez-vous qu'il passe.
Solution :
// build.gradle
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.9.2'
}
// CalculatorTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class CalculatorTest {
@Test
public void testMultiplication() {
assertEquals(6, 2 * 3);
}
}
19.2 Exercices pour les bases de JUnit
Exercice 1 : Utilisation des annotations de base
- Créez une classe de test
CalculatorTest. - Utilisez les annotations @BeforeEach et @AfterEach pour initialiser et nettoyer les ressources.
- Écrivez un test pour vérifier que
4 - 2 = 2. - Assurez-vous que les méthodes de configuration et de nettoyage sont exécutées avant et après chaque test.
Solution :
// CalculatorTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
public class CalculatorTest {
private Calculator calculator;
@BeforeEach
public void setUp() {
calculator = new Calculator();
}
@AfterEach
public void tearDown() {
calculator = null;
}
@Test
public void testSubtraction() {
assertEquals(2, calculator.subtract(4, 2));
}
}
Exercice 2 : Utilisation des assertions
- Écrivez des tests utilisant
assertTrue,assertFalse,assertNull, etassertNotNull. - Créez une méthode de test pour vérifier qu'une chaîne de caractères est vide.
- Vérifiez qu'un objet est nul après l'avoir défini sur
null.
Solution :
// StringUtilsTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
public class StringUtilsTest {
@Test
public void testIsEmpty() {
String str = "";
assertTrue(str.isEmpty());
}
@Test
public void testIsNotEmpty() {
String str = "Hello";
assertFalse(str.isEmpty());
}
@Test
public void testIsNull() {
String str = null;
assertNull(str);
}
@Test
public void testIsNotNull() {
String str = "JUnit";
assertNotNull(str);
}
}
19.3 Exercices pour les tests paramétrés
Exercice 1 : Création de tests paramétrés avec JUnit 4
- Créez une classe de test paramétré pour vérifier la multiplication de deux nombres.
- Utilisez @RunWith(Parameterized.class) et @Parameters pour fournir des données de test.
- Exécutez les tests avec différents ensembles de données.
Solution :
// MultiplicationTest.java
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.util.Arrays;
import java.util.Collection;
@RunWith(Parameterized.class)
public class MultiplicationTest {
private int a;
private int b;
private int expected;
public MultiplicationTest(int a, int b, int expected) {
this.a = a;
this.b = b;
this.expected = expected;
}
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
{ 1, 2, 2 },
{ 2, 3, 6 },
{ 3, 5, 15 },
{ 4, 4, 16 }
});
}
@Test
public void testMultiply() {
assertEquals(expected, a * b);
}
}
Exercice 2 : Création de tests paramétrés avec JUnit 5
- Créez une classe de test paramétré pour vérifier la division de deux nombres.
- Utilisez @ParameterizedTest et @CsvSource pour fournir des données de test.
- Exécutez les tests avec différents ensembles de données.
Solution :
// DivisionTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
public class DivisionTest {
@ParameterizedTest
@CsvSource({
"6, 2, 3",
"9, 3, 3",
"10, 2, 5",
"12, 4, 3"
})
void testDivide(int dividend, int divisor, int expected) {
assertEquals(expected, dividend / divisor);
}
}
19.4 Exercices pour les faux objets (Mocking)
Exercice 1 : Création de mocks avec Mockito
- Créez un mock d'une interface
UserRepository. - Utilisez ce mock pour tester un service
UserServicequi dépend deUserRepository. - Écrivez un test pour vérifier que
UserServiceappelle la méthodefindUserByIddeUserRepository.
Solution :
// UserServiceTest.java
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class UserServiceTest {
@Mock
private UserRepository userRepository;
@InjectMocks
private UserService userService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testFindUserById() {
User user = new User("john.doe", "John", "Doe");
when(userRepository.findUserById(1)).thenReturn(user);
User foundUser = userService.findUserById(1);
assertNotNull(foundUser);
assertEquals("john.doe", foundUser.getUsername());
verify(userRepository, times(1)).findUserById(1);
}
}
Exercice 2 : Utilisation de @Mock, @InjectMocks, et @Spy
- Créez un service
OrderServicequi dépend dePaymentService. - Utilisez @Mock pour créer un mock de
PaymentServiceet @InjectMocks pour injecter le mock dansOrderService. - Écrivez un test pour vérifier que
OrderServiceappelle la méthodeprocessPaymentdePaymentService.
Solution :
// OrderServiceTest.java
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class OrderServiceTest {
@Mock
private PaymentService paymentService;
@InjectMocks
private OrderService orderService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
}
@Test
public void testProcessOrder() {
Order order = new Order(100.0);
when(paymentService.processPayment(order.getAmount())).thenReturn(true);
boolean result = orderService.processOrder(order);
assertTrue(result);
verify(paymentService, times(1)).processPayment(order.getAmount());
}
}
19.5 Exercices pour les tests de performances
Exercice : Utilisation de JMH pour mesurer les performances
- Créez une classe de benchmark pour mesurer les performances de la méthode
factoriald'une classeMathUtils. - Utilisez JMH pour configurer le benchmark et exécuter les tests de performance.
Solution :
// MathUtils.java
public class MathUtils {
public long factorial(int n) {
if (n <= 1) return 1;
else return n * factorial(n - 1);
}
}
// FactorialBenchmark.java
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import java.util.concurrent.TimeUnit;
@State(org.openjdk.jmh.annotations.Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class FactorialBenchmark {
private MathUtils mathUtils = new MathUtils();
@Benchmark
@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(1)
public void testFactorial() {
mathUtils.factorial(10);
}
}
19.6 Exercices pour l'intégration avec Jenkins
Exercice : Configuration d'un job Jenkins pour exécuter des tests JUnit
- Créez un projet Maven avec des tests JUnit.
- Configurez un job Jenkins pour exécuter les tests à chaque commit.
- Configurez Jenkins pour publier les rapports de tests JUnit.
Solution :
- Créez le projet Maven avec les tests comme dans l'exercice 19.1.
- Suivez les étapes du chapitre 16 pour configurer Jenkins et exécuter les tests JUnit.
19.7 Exercices pour les rapports de test
Exercice : Génération et visualisation des rapports de test
- Utilisez Maven pour générer des rapports de tests JUnit.
- Configurez Jenkins pour afficher les rapports de tests après l'exécution des builds.
- Analysez les résultats des tests et identifiez les tests échoués.
Solution :
- Créez le projet Maven avec les tests comme dans l'exercice 19.1.
- Suivez les étapes du chapitre 17 pour configurer Jenkins et visualiser les rapports de tests.
19.8 Étude de cas
Exercice : Application des concepts dans un projet réel
- Choisissez un projet existant ou créez un nouveau projet.
- Intégrez JUnit pour les tests unitaires, Mockito pour les mocks, et JMH pour les tests de performance.
- Configurez Jenkins pour l'intégration continue.
- Génrez et analysez les rapports de tests.
- Documentez le processus et les résultats obtenus.
Solution :
- Appliquez les connaissances et les exemples fournis dans les chapitres précédents pour compléter cet exercice de manière autonome.
Résumé du chapitre :
- Les exercices pratiques renforcent les compétences acquises en écriture et exécution de tests unitaires avec JUnit.
- Chaque module comprend des exemples pratiques et des exercices pour une application concrète des concepts.
- La pratique régulière et l'application des bonnes pratiques garantissent une meilleure compréhension et maîtrise de JUnit et des tests unitaires.