Подтвердить что ты не робот

Поведение, странное поведение в JUnit

Я пытаюсь написать unit test, для которого требуются потоки mulitple. Тем не менее, кажется, что потоки просто останавливаются частично через выполнение. Рассмотрим следующий код:

public class Test {
    @org.junit.Test
    public void TestThreads() {
        new Thread(new Runnable() {
            public void run() {
                for (int i = 1; i < 1000; i++) System.out.println(i);
            }
        }).start();
    }
}

Если я запустил этот unit test, он вообще перестанет отображать вывод где-то между 140-180. Если я конвертирую этот код в обычный класс и запускаю его, он отлично работает. Кто-нибудь знает, что мне здесь не хватает?

Спасибо, - Эндрю.

4b9b3361

Ответ 1

Вы можете использовать Thread.join(), чтобы предотвратить завершение теста до того, как новый поток выполнит свою задачу:

@org.junit.Test
public void TestThreads() throws InterruptedException {
    Thread t = new Thread(new Runnable() {
        public void run() {
            for (int i = 1; i < 1000; i++) System.out.println(i);
        }
    });
    t.start();
    t.join();
}

Как правило, JVM завершается, когда последний не-демонный поток завершается. Вы могли бы ожидать, что просто вызов t.setDaemon(false) в потоке не позволит JVM выйти до завершения задачи. Однако junit будет вызывать System.exit(), когда основной поток завершен.

Как отмечает Гас в комментариях: "вам нужно join(), потому что start() не блокирует".

Он исправит, что вы могли бы также вызвать run() в этом минимальном примере. Однако я предполагаю, что вы начинаете поток, потому что хотите, чтобы он запускался одновременно с другим потоком. Вызов run() в потоке помечен как возможная ошибка FindBugs - если вы просто собираетесь называть run(), вы, вероятно, просто захотите реализовать Runnable вместо использования Thread.

Ответ 2

В функции TestThread JUnit не может сказать, что вы породили новый поток. Он восстанавливает любые объекты, созданные в функции, как только заканчивается функция (последняя строка достигнута) и не знает о потоке.

По этой причине вы видите "Выход" из потока, пока он не будет убит. Если вы хотите дождаться завершения Thread, вы можете использовать Thread.join (сразу после вызова Thread.start()), чтобы дождаться результата или использовать wait-notify для некоторого объекта.

Также был найден этот вопрос: JUnit завершает дочерние потоки

Ответ 3

Вероятно, заканчивается родительский поток, выполняющий тест. Если вы можете избежать этого, не создавайте в тестах новый поток. Я бы создал новый класс, реализующий runnable, а затем проверил этот класс, который я просто вызывал на этом объекте. Вам не нужно проверять планирование потоков как часть ваших тестов. Надеемся, что команда разработчиков java-языка будет охватывать:)