2017-09-24 5 views
1

Comment tester un code qui s'exécute dans le service d'exécution? Dans ma situation,Comment tester unitairement un extrait de code exécuté à l'intérieur du service d'exécution, au lieu de Thread.sleep (time)

public void test() { 
    Runnable R = new Runnable() { 
     @Override 
     public void run() { 
      executeTask1(); 
      executeTask2(); 
     } 
    }; 

    ExecutorService executorService = Executors.newSingleThreadExecutor(); 
    executorService.submit(R); 
} 

Quand je suis test unitaire, je voudrais faire quelques validations cette méthode est exécutée.

Je l'exécute dans un service d'exécuteur, car il effectue certaines opérations réseau.

Lors de mes tests unitaires, j'ai dû attendre que cette méthode soit terminée. Y at-il une meilleure façon de le faire, au lieu d'attendre Thread.sleep(500).

Unité extrait de code de test:

@Test 
public void testingTask() { 
    mTestObject.test(); 
    final long threadSleepTime = 10000L; 
    Thread.sleep(threadSleepTime); 
    verify(abc, times(2)) 
      .acquireClient(a, b, c); 
    verify(abd, times(1)).addCallback(callback); 
} 

Note: Je passe un objet de service exécuteur testamentaire dans cette catégorie constructeur. Je voudrais savoir s'il y a une bonne façon de tester au lieu d'attendre le temps de sommeil.

Répondre

1

Quelques possibilités:

  • extraire le code de service de l'exécuteur et le tester « autonome » par exemple dans votre exemple test de executeTask1() et executeTask2() eux-mêmes ou encore ensemble, mais tout simplement pas en exécutant eux dans un fil séparé. Le fait que vous « faire passer un objet de service exécuteur testamentaire dans cette catégorie constructeur » aide ici puisque vous pourriez avoir

    • Un test qui se moque du service de l'exécuteur et vérifie que vous soumettez le bon runnable à elle
    • Test (s) qui vérifient le comportement de executeTask1() et executeTask2() sans les exécuter dans un thread séparé.
  • Utilisez un CountDownLatch pour permettre à votre code en exécutant service pour indiquer au fil de test quand il est fini. Par exemple:

    // this will be initialised and passed into the task which is run by the ExecutorService 
    // and will be decremented by that task on completion 
    private CountDownLatch countdownLatch; 
    
    @Test(timeout = 1000) // just in case the latch is never decremented 
    public void aTest() { 
        // run your test 
    
        // wait for completion 
        countdownLatch.await(); 
    
        // assert 
        // ... 
    } 
    
  • Accepter que vous devez attendre que l'autre fil pour remplir et cacher la laideur des Thread.sleep appels dans vos cas de test en utilisant Awaitility. Par exemple:

    @Test 
    public void aTest() { 
        // run your test 
    
        // wait for completion 
        await().atMost(1, SECONDS).until(taskHasCompleted()); 
    
        // assert 
        // ... 
    } 
    
    private Callable<Boolean> taskHasCompleted() { 
        return new Callable<Boolean>() { 
         public Boolean call() throws Exception { 
          // return true if your condition has been met 
          return ...; 
         } 
        }; 
    } 
    
+0

Mais notez que mes méthodes, dites ici executeTask1() et executeTask2(), voici les méthodes privées et ils n'ont pas tous les types de retour. Je ne trouve pas cette méthode de test fiable. Pouvez-vous suggérer pourquoi c'est un moyen fiable? –

+0

Je ne pense pas que je puisse offrir beaucoup d'aide sur les spécificités de tester 'executeTask1()' et 'executeTask2()' sans voir leur implémentation. Je ne pense pas que je peux offrir de l'aide avec ceci: "Je ne trouve pas cette manière de tester fiable" sans voir ce que vous avez essayé jusqu'ici. Si vous essayez de retravailler votre code pour faciliter l'option 1 ou l'option 2 de ma réponse, alors une question distincte qui traite de vos problèmes spécifiques et fournit un [MCVE] (https://stackoverflow.com/help/mcve) pourrait aider ? – glytching