2017-02-15 11 views
1

私は新しいスレッドでリスナーにイベントを渡す持つEventEmitterを作成し、以前に完了した場合に完了していないようです受信された:子スレッドは親が

@Component 
public class StudentRegisteredEventListener implements EventListener { 

@Override 
public void beNotifiedOfEvent(Event e) { 
    try { 
     Thread.sleep(2000); 
    } catch (InterruptedException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 

    StudentRegisteredEvent studentRegisteredEvent = (StudentRegisteredEvent) e; 
    System.out.println("Received student registered event! Student's name is: "+studentRegisteredEvent.getRegisteredStudent()); 
} 

} 

私は次のJUnitテストを持っている:

@Test 
public void test_emitter_notifies_listener() { 
    //given 
    EventEmitter emitter = new CachedThreadPoolEventEmitter(); 
    //StudentRegisteredEvent event = new StudentRegisteredEvent(); 

    EventListener listener = Mockito.mock(StudentRegisteredEventListener.class); 

    Student registeredStudent = new Student(); 
    registeredStudent.setName("studentName"); 

    //when 
    emitter.subscribe(listener,StudentRegisteredEvent.class); 
    emitter.publish(new StudentRegisteredEvent(registeredStudent)); 

    //then 

    System.out.println("end of test"); 
} 

私のPR oblemは、親スレッドが "beNotifiedOfEvent"呼び出しの終わりより前に終了すると、リスナーメソッドからの行は出力されないので、コンソール上では "end of test"しか表示されません。

私が興味を持っているのは、この動作の理由と、これがテストのコンテキスト外で動作するかどうかです。 Spring MVCコントローラからイベントを公開する予定です。これは、親スレッドが実行された後に完了することが保証されていますか?

答えて

1

テストのコンテキスト内で動作しない場合は、テストのコンテキスト外で動作する可能性があるという言葉は使用しないでください。あなたのテストが最初に正しく働くようにしてください。

テストが正常に終了するようにするには、それが生成されたすべてのスレッドが終了するまで待つ必要があります。次のようにあなたのExecutorが実際にExecutorServiceであると仮定すると、これが行われます:

executorService.shutdown(); 
try 
{ 
    executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); 
} 
catch (InterruptedException e) 
{ 
    ... 
} 

上記のコードを実行している間、あなたのタスクが完了するまで実行されなければならないので、あなたのタスクが終了する前にメッセージが右側に表示されるはずです。

2

スレッドが終了するのではなく、プロセス全体です。 JUnit kills the process when the test finishesだから、デーモンではないスレッドでさえ、JUnitテストプロセスを生かし続けることはできません。(実際のテストが終わった後、誰もテストプロセスを実行したくないということはまったく簡単です)。 In Java, threads do not have a hierarchyには、「親」スレッドというものはありません。しかし、ほぼすべてのアプリケーションには、ある種の「メイン」スレッドがあります。 JUnitは独自のメインスレッドを持ち、内部でテストを実行し、最後にSystem.exit(0);を呼び出します。

タイムアウトしたイベントをテストする場合は、スレッドのテストケースを明示的に待機する必要があります。また、Thread.sleep-sの代わりにScheduledExecutorServiceを使用することをお勧めします。

関連する問題