Test mauvaise JUnit à l'aide springframework a des appels Thread.sleep fragiles (). Comment réparer?

StackOverflow https://stackoverflow.com/questions/4433423

Question

J'ai récemment rejoint un groupe avec des problèmes graves de tests JUnit. Un problème est un test à long 8 minutes! Le test comporte plusieurs sections; chacun fait des appels à org.springframework.context.ApplicationEventPublisher.publishEvent () suivi par Thread.sleep () de diverses quantités de temps, teste alors les conditions.

Il y a plusieurs problèmes évidents avec cette approche, le calendrier des appels Thread.sleep () est fragile:

  • tests échouent parfois sur des machines occupées; et

  • tests prennent beaucoup trop de temps quand ils ne manquent pas.

La piscine sur laquelle ces événements sont traités accessibles pour tester et est-il un appel pour voir si la cascade d'événements a mis au repos?

Était-ce utile?

La solution

Vous pouvez remplacer le applicationEventMulticaster par défaut en ajoutant cet identifiant de haricots à votre contexte d'application.

Au lieu de la SimpleApplicationEventMulticaster par défaut, vous pouvez définir une TaskExecutor sur ce haricot pour effectuer la publication d'événements de manière asynchrone dans plusieurs threads.

Ou vous pourriez mettre en œuvre votre propre Multicaster, qui imprime qui écouteur d'événement a pris si longtemps ou bloquait, pour combien de temps et sur les événements. Cela pourrait vous aider à traquer le vrai problème de la 8-Minute-Testcase.

Fait intéressant, le JavaDoc du SimpleApplicationEventMulticaster, qui est utilisé par défaut au printemps lorsque vous utilisez ApplicationContext, déclare ce qui suit:

  

Par défaut, tous les auditeurs sont invoqués dans le thread appelant. Cela permet au danger d'un auditeur voyous bloquant toute l'application , mais ajoute des frais généraux minimes. Spécifier une TaskExecutor alternative aux auditeurs ont exécutés dans différents fils, par exemple à partir d'un pool de threads.

Autres conseils

Il convient de mentionner que le code de test qui appelle effectivement des services externes sont des tests d'intégration et non pas des tests unitaires. Si vous êtes vraiment des tests unitaires ici, vous devriez remplacer ces appels avec des simulacres. De cette façon, vous pouvez mieux contrôler les valeurs renvoyées à votre logique métier et tester dans des conditions spécifiques. En outre, comme vous l'avez vu, tout cela, mais élimine les faux positifs dus à l'extérieur (non-code) situations. Il est évident que ces tests ne sont pas un échec, l'installation qu'ils attendent à utiliser est.

I (intentionnellement) éviter printemps, donc je ne suis pas sûr que je peux aider avec les détails, mais simplement regarder la question du sommeil, vous pouvez utiliser quelque chose comme WaitFor dans tempus-fugit (prise sans vergogne) au scrutin pour un Condition plutôt que « le sommeil et l'espoir ». Ce n'est pas idéal et le plus souvent un changement de la façon dont vous test (comme suggéré avant) est préférable, mais cela ne signifie que vous obtenez à grain plus fin « attend » qui sont plus susceptibles d'éviter la course conditions / tests floconneux et accélèrent généralement le test.

Voyez si vous trouvez qu'il est utile pour les détails et revenir après le projet !

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top