Dernière modification : 11/11/2022

Tester une méthode privée avec Spring

 

Tester une méthode privée (avec Spring) peut être un test unitaire intéressant, surtout si elle réalise des actions sensibles. Cependant, transformer une méthode initialement privée en méthode publique en dehors des tests unitaires dégrade l'application, pouvant créer des anomalies. Par conséquent, l'outil présenté ci-dessous n'est à utiliser que lors des tests unitaires.

 

Dans ce ticket nous nous baserons sur l'implémentation suivante : Template basique de test Java

 

1. Test unitaire avec une méthode publique

Créer la méthode publique isEmpty dans la classe MyClass :

/**
 * Check if {@code txt} is null or empty
 * 
 * @param txt the text
 * @return {@code true} if {@code txt} is null or empty, {@code false} otherwise
 */
public boolean isEmpty(String txt) {
    return txt == null || txt.length() == 0;
}

 

Cette méthode renvoie true si la chaîne de caractère fournie en paramètre est nulle ou vide, false sinon. Celle-ci pourrait être utilisée dans des méthodes de la classe MyClass.

Les tests de cette méthode pourraient être les suivants (dans la classe MyClassTest) :

/**
 * Test the isEmpty method.
*/ @Test public void checkIsEmptyMethod() { Assertions.assertTrue(this.myClass.isEmpty("")); Assertions.assertTrue(this.myClass.isEmpty(null)); Assertions.assertFalse(this.myClass.isEmpty(" ")); Assertions.assertFalse(this.myClass.isEmpty("a")); Assertions.assertFalse(this.myClass.isEmpty("abc")); }

 

2. Test unitaire avec une méthode privée et Spring

Cependant, si la méthode isEmpty devient privée, alors les tests ci-dessus seraient invalides et ne compileraient pas. Pour quand même réaliser les tests sur notre méthode, nous devons la rendre accessible.

Ajouter la dépendance spring-test suivante dans le fichier pom.xml (si absente) :


    org.springframework
    spring-test
    5.3.23
    test

 

Nous allons utiliser la méthode ReflectionTestUtils.invokeMethod disponible dans les dépendances de Spring. Les tests de isEmpty pourraient être les suivants (toujours dans la classe MyClassTest) :

/**
 * Test the isEmpty method.
 */
@Test
public void checkIsEmpty() {
    Assertions.assertTrue((boolean) ReflectionTestUtils.invokeMethod(this.myClass, "isEmpty", ""));
    Assertions.assertTrue((boolean) ReflectionTestUtils.invokeMethod(this.myClass, "isEmpty", new Object[] { null }));
    Assertions.assertFalse((boolean) ReflectionTestUtils.invokeMethod(this.myClass, "isEmpty", " "));
    Assertions.assertFalse((boolean) ReflectionTestUtils.invokeMethod(this.myClass, "isEmpty", "a"));
    Assertions.assertFalse((boolean) ReflectionTestUtils.invokeMethod(this.myClass, "isEmpty", "abc"));
}

La méthode ReflectionTestUtils.invokeMethod permet d'invoquer la méthode isEmpty. Elle prend en paramètre un instance de la classe MyClass (MyClass.class si la méthode isEmpty est statique), le nom de la méthode à tester et les paramètres de la méthode (un tableau d'Object si une ou plusieurs valeurs sont nulles).