2014-02-13 5 views
0

У меня есть код, который вызывает другой поток, а бизнес-логика - в методе run(). экс-код:Тестирование потоков с Junits

public class Test { 
    protected boolean stripObjects ; 
    protected boolean catcharchiveObjects 
    public void runZipper(boolean strip,boolean createarchive) {   
     stripObjects = strip; 
     catcharchiveObjects = createcatcharchive; 
     exThread czct = new exThread();   
     czct.start();   
    } 

    private class exThread extends Thread() { 
     public void run() { 
     try {           
      if (strip) 
       return; 
       if(checkAction()) 
       { 
       .... 
       } 
      //some business logic which generates a zipfile 
      } 
     catch (Exception e) { 
      } 
     } 
    } 
} 

Я написал JUnit для приведенного выше кода, как показано ниже.

public class JunitTest { 
    public void testRunZipper() { 
     Test testEx = new Test(); 
     testEx.runZipper(false,true); 
     //assert statement to check whether zip file is created 
    } 
} 

Когда я запускаю тестовый тест Junit, он терпит неудачу, и почтовый индекс не создается.

Затем я запустил Junit в режиме отладки, и я вижу, когда вызывается czct.start(), он переходит в метод run. Но он сразу же вернулся к вызывающей функции, то есть runZipper().

Теперь я изменил run(), чтобы добавить sysout в качестве первого оператора в нем. Теперь, когда я запускаю Junit, он печатает все, что есть в sysout, а затем управление возвращается к runZipper().

Может ли кто-нибудь помочь мне в решении этого, чтобы он выполнял все инструкции в run().

Заранее спасибо.

+0

Можете ли вы разместить [SSCCE] (http://sscce.org/)? Вы говорите о многих вещах, которые не отображаются в коде. –

+0

Я не знаю, как это могло быть, они отлично работают на моем ПК – Jesse

+0

Я изменил свой вопрос. Надеюсь, поможет. Но мне жаль, что я не могу дать компилируемый код и целые детали, так как он очень большой и конфиденциальный. – user2179627

ответ

1

Вам необходимо добавить «наблюдателей» в код классов, которые выполняют какую-либо обработку с несколькими потоками, в то же время требуя модульного тестирования. Идея такова: после каждого логического шага класс посылает сигнал наблюдателю. Как правило, в среде prod никто не наблюдает за этими сигналами, в то время как при тестировании на единицу измерения или функциональных тестах вы добавляете наблюдателя с ограниченным временем защелкой.

Вот пример

public class MultithreadingInUnitTest { 
    private Watcher watcher = new DefaultWatcher(); 

    public void runZipper() { 
     exThread czct = new exThread(); 
     watcher.process(WatchedEvent.EVENT_1); 
     czct.start(); 
    } 

    private class exThread extends Thread { 
     public void run() { 
      try { 
       //some business logic which generates a zipfile 
      } catch (Exception e) { 
      } finally { 
       watcher.process(WatchedEvent.EVENT_2); 
      } 
     } 
    } 


    public void setWatcher(Watcher watcher) { 
     this.watcher = watcher; 
    } 

    private class DefaultWatcher implements Watcher { 
     @Override 
     public void process(WatchedEvent event) { 
      //Noop for production use 
     } 
    } 
} 

interface Watcher { 
    public void process(WatchedEvent event); 
} 

enum WatchedEvent { 
    EVENT_1, EVENT_2 
} 

Это как вам блок-тест он. Примечание. Предел времени фиксации

class JunitTest { 
    public void testRunZipper() throws InterruptedException { 
     final CountDownLatch latch = new CountDownLatch(1); 
     Watcher watcher = new Watcher() { 
      @Override 
      public void process(WatchedEvent event) { 
       if (event == WatchedEvent.EVENT_2) { latch.countDown(); } 
      } 
     }; 
     MultithreadingInUnitTest testEx = new MultithreadingInUnitTest(); 
     testEx.setWatcher(watcher); 

     testEx.runZipper(); 
     latch.await(10, TimeUnit.SECONDS); 
     if (latch.getCount() != 0) { Assert.fail("Latch was never triggered"); } 

     //assert statement to check whether zip file is created 
    } 

} 
Смежные вопросы