Au cas où vous auriez vraiment à tester des méthodes privées dans JUnit. J'oublie comment le mettre en œuvre régulièrement, donc je ne l'oublierai jamais une fois que je l'écrirai fermement dans l'article. Je vais l'écrire avec le motif.
Considérez une classe avec une méthode privée comme celle ci-dessous.
public class MyClass {
private String introduceMyself(String name){
return "my name is " + name + ".";
}
}
Le test de la méthode privée introdMyself de MyClass peut être effectué en utilisant la réflexion comme suit:
import com.example.MyClass;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import static org.assertj.core.api.Assertions.assertThat;
public class MyClassTest {
@Test
void testIntroduceMyself01() throws Exception {
MyClass targetClass = new MyClass();
//Obtenir des informations sur la méthode testée
Method method = MyClass.class.getDeclaredMethod("introduceMyself", String.class);
//Supprimer les restrictions d'accès aux méthodes
method.setAccessible(true);
//Appel de méthode
String selfIntroduction = (String) method.invoke(targetClass,"John");
//Affirmez le résultat
assertThat(selfIntroduction).isEqualTo("my name is John.");
}
}
Ce qui précède convient aux cas de test normaux, mais soyez prudent lorsqu'une exception est levée à partir d'une méthode privée.
Les exceptions qui se produisent dans la méthode # invoke seront encapsulées dans la classe InvocationTargetException. Par conséquent, il est nécessaire d'extraire l'exception de cause avant de faire une assertion.
public class MyClass {
private String introduceMyself(String name){
//Lève une exception si l'argument est vide
if(name.isEmpty()){
throw new IllegalArgumentException("argument must not be empty.");
}
return "my name is " + name + ".";
}
}
public class MyClassTest {
@Test
void testIntroduceMyself02() throws Exception {
MyClass targetClass = new MyClass();
Method method = MyClass.class.getDeclaredMethod("introduceMyself", String.class);
method.setAccessible(true);
try {
method.invoke(targetClass, "");
fail("this code should not has been reached.");
}catch (InvocationTargetException e) {
//Assert après avoir récupéré l'exception de cause avec getCause
assertThat(e.getCause()).isInstanceOf(IllegalArgumentException.class);
}
}
}
Si vous voulez passer null comme argument de la méthode à appeler par réflexion, vous devez passer un tableau Object qui a null comme élément, donc soyez prudent ici également.
method.invoke(targetClass, new Object[]{null});
//Ce n'est pas bien
method.invoke(targetClass, null);
Comme je l'ai dit jusqu'à présent, les méthodes privées ne devraient pas être testées à l'unité en principe.
La méthode privée est, pour ainsi dire, un processus interne coupé de la méthode publique (protégée). En testant de force le traitement interne avec réflexion, le code de test devient dépendant de l'implémentation interne, qui devient une barrière lors de la refactorisation ou de l'ajout de fonctions.
L'intégralité peut être testée via la méthode d'appel s'il s'agit d'une méthode privée bien conçue. S'il existe une branche qui doit être appelée individuellement pour les méthodes privées, il s'agit en fait de code mort et vous devez revoir votre implémentation.
--Réflexion requise pour appeler la méthode privée
Recommended Posts