Lorsque je teste l'exécution d'une méthode qui crée un thread enfant, le test JUnit se termine avant le thread enfant et le tue.
Comment puis-je forcer JUnit à attendre que le thread enfant termine son exécution ?
Lorsque je teste l'exécution d'une méthode qui crée un thread enfant, le test JUnit se termine avant le thread enfant et le tue.
Comment puis-je forcer JUnit à attendre que le thread enfant termine son exécution ?
Après avoir lu la question et certains commentaires, il semble que ce dont vous avez besoin soit une technique de test unitaire des opérations asynchrones . doSomething() renvoie immédiatement, mais vous voulez que le code de test attende son achèvement, puis effectue quelques validations.
Le problème est que le test n'est pas conscient des threads créés par l'appel, il n'a donc apparemment aucun moyen de les attendre. On peut penser à de nombreuses façons sophistiquées (et probablement imparfaites) de résoudre ce problème, mais à mon avis, il y a un problème de conception ici. Un test unitaire doit simuler un client d'une API et ne doit rien présumer de l'implémentation ; il doit seulement tester la fonctionnalité, telle que reflétée par l'API et sa documentation. Par conséquent, j'éviterais d'essayer de détecter et de suivre les threads créés par l'appel asynchrone. Au lieu de cela, j'améliorerais l'API de la classe testée, si nécessaire. La classe à laquelle appartient l'appel asynchrone devrait fournir un mécanisme de détection de la terminaison. Je peux penser à 3 façons, mais il y en a probablement d'autres :
Permet d'enregistrer un écouteur qui sera notifié une fois l'opération terminée.
Fournir une version synchrone de l'opération. L'implémentation peut appeler la version asynchrone, puis bloquer jusqu'à la fin. Si la classe ne doit pas exposer une telle méthode, sa visibilité peut être réduite à package protected, afin que le test puisse y accéder.
En utilisant le modèle d'attente et de notification, sur un objet visible.
Si la classe ne fournit pas un tel mécanisme, alors elle n'est pas vraiment testable, et pire, elle n'est probablement pas très réutilisable non plus.
Essayez d'utiliser [thread.join()](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#join()) sur le fil de discussion créé. Cela attendra que ce thread meure.
Edit : pour éviter cela, essayez Thread.getThreadGroup().setDaemon(true);
dans le test, ou peut-être dans le setUp()
méthode. Je ne l'ai pas testé cependant.
Un groupe de threads de démon est automatiquement détruit lorsque son dernier thread est arrêté ou que son dernier groupe de threads est détruit.
Je me demande si JUnit appelle System.exit()
ou autre chose dès que le test est terminé, cependant.
La technique de base que @Eyal a décrite est ce que ConcurrentUnit est destiné. L'usage général est le suivant :
Voir la page ConcurrentUnit pour plus d'informations.
Peut-être que vous pouvez regrouper vos fils avec un ExecutorService puis utiliser arrêt et awaitTermination méthode ?
La condition est d'utiliser Runnable ou Future, pas les Threads eux-mêmes.
while (s.isRunning()) {
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Vous pouvez essayer de bloquer le thread de JUnit et lui demander d'attendre que votre thread soit terminé. Le site Thread.sleep()
est nécessaire pour que votre fil ne monopolise pas le CPU. Dans cet exemple, s serait votre thread, vous aurez besoin d'une fonction isRunning()
afin de pouvoir vérifier si le thread est toujours en cours d'exécution à chaque fois que la méthode SLEEP_TIME
millisecondes. Je sais que ce n'est pas la meilleure solution, mais si vous n'avez que 2 fils et que vous ne voulez pas que JUnit tue votre fil, cela fonctionne. La boucle while permet à ce thread JUnit de rester en vie et d'attendre que l'autre thread se termine.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.