Dernière modification : 11/11/2022

Tester une méthode privée

 

Tester une méthode privée 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

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.

Pour ce faire, créer dans la classe de test la méthode suivante :

private Method getIsEmptyMethod() throws NoSuchMethodException {
    Method method = MyClass.class.getDeclaredMethod("isEmpty", String.class); // isEmpty method and String parameter declaration
    method.setAccessible(true);
    return method;
}

Cette méthode retourne une déclaration accessible de la méthode isEmpty de la classe MyClass. Nous déclarons également que cette méthode prend un paramètre de type String.

 

Les tests de isEmpty pourraient être les suivants (toujours dans la classe MyClassTest) :

/**
 * Test the isEmpty method.
 * 
 * @throws NoSuchMethodException
 * @throws InvocationTargetException
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 */
@Test
public void checkIsEmptyMethod()
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException {
    Assertions.assertTrue((boolean) this.getIsEmptyMethod().invoke(this.myClass, new Object[] { "" }));
    Assertions.assertTrue((boolean) this.getIsEmptyMethod().invoke(this.myClass, new Object[] { null }));
    Assertions.assertFalse((boolean) this.getIsEmptyMethod().invoke(this.myClass, new Object[] { " " }));
    Assertions.assertFalse((boolean) this.getIsEmptyMethod().invoke(this.myClass, new Object[] { "a" }));
    Assertions.assertFalse((boolean) this.getIsEmptyMethod().invoke(this.myClass, new Object[] { "abc" }));
}

La méthode invoke permet d'invoquer la méthode isEmpty. Elle prend en paramètre un instance de la classe MyClass et un tableau d'Object contenant les arguments de la méthode à tester.

Remarque : Dans le cas d'un test d'une méthode statique, le premier paramètre de la méthode invoke doit être à null.