2015-03-16 7 views
0

Я столкнулся с проблемой, которая заставила меня по-настоящему застопориться. Я уверен, что это что-то вроде junit, с которым я не очень разбираюсь.Странное поведение при тестировании многопоточности в junit

Давайте Tak очень простой класс:

package incubate.thread; 

import java.util.logging.Level; 
import java.util.logging.Logger; 

public class Sleeper implements Runnable{ 

    @Override 
    public void run(){ 
     try { 
      Thread.sleep(5000l); 
      System.out.println("done snoozing"); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(Sleeper.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

Написать очень простой тест для резьбы

package incubate.thread; 

import org.junit.Test; 

public class SleeperTest { 

    @Test 
    public void testSnooze() throws Exception { 
     new Thread(new Sleeper()).start(); 
    } 

    public static void main(String...args){ 
     new Thread(new Sleeper()).start(); 
    } 
} 

Вы заметите, я включил в «основной» метод внутри тестового класса. Когда вы вызываете junit для выполнения «testSnooze», тест сразу же выходит без запуска потока.

Если, однако, вы вызываете основной метод, поток работает просто отлично; он откладывает, а затем печатает быстрое сообщение в конце

Как насчет junit вызывает такое поведение?

+1

Когда вы вводили этот вопрос или какой-либо из ваших восьми предыдущих вопросов, там был большой оранжевый ** «Как отформатировать **» справа. Стоит прочитать. И в то время, как и при наборе любого из ваших восьми ответов *, была полная панель инструментов форматирования над текстовым полем. И ** [?] ** кнопка с большой помощью. И область предварительного просмотра внизу, чтобы проверить ваши результаты. Пожалуйста, используйте их. –

+0

Спасибо. Это отлично выглядит сейчас – mainas

+0

Спасибо Томасу, он сделал эту работу. Я просто пожаловался. :-) –

ответ

1

Ваш testSnooze вернется, не дожидаясь окончания резьбы. Не уверен, что произойдет с оставшейся спальной нитью, когда JUnit закончит. Я думаю, что JUnit просто выходит из виртуальной машины, не дожидаясь остаточных потоков.

Если вы вызываете основной метод, виртуальная машина будет ждать завершения любых потоков, отличных от deamon.

для теста работать только ждать завершения потока:

@Test 
public void testSnooze() throws Exception { 
    Thread t = new Thread(new Sleeper()); 
    t.start(); 
    t.join(); 
} 
+0

Это не будет обрабатывать утверждения внутри порожденных нитей. См. Здесь: http://stackoverflow.com/questions/2596493/junit-assert-in-thread-throws-exception – spudone

2

Далее ответ ThomasStets', я хотел бы предложить рассмотреть вопрос о тестировании run() метод сам по себе, не вызывая потока start().

Целью тестирования является проверка кода мы писали, мы не должны проверить код, который мы не писал - поэтому для модульного тестирования, вызов метода run() непосредственно должно быть достаточно.

Однако, мы должны проверить, что код, который мы написали, работает с кодом, который мы не писали. Если это так просто, как потоки, я думаю, что это будет рассмотрено в приемочных тестах (проверка черного ящика на точке входа в систему), нет никакого способа написать интеграционный тест для этого.

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