2016-12-09 6 views
0

자바에서 Akka 액터를 테스트하려고합니다. 테스트가하려고하는 것입니다. 코드는 다음과 같습니다.Akka 액터가 살아 있고 이벤트 스트림에 등록되어 있는지 확인하는 방법

  • 이 액터는 그의 생성자에서 evenstream을 구독합니다.
  • 액터는 액터 시스템에서 normal actorOf를 사용하여 테스트에서 생성됩니다.
  • 이것은 ActorRef를 반환하지만 실제 액터는 장면 뒤에서 비동기 적으로 생성됩니다.
  • 테스트시 이벤트 스트림에 메시지를 게시합니다.
  • 그러나 액터가 비동기 적으로 생성되므로 메시지가 액터가 이벤트 스트림에 등록되기 전에 이벤트 스트림에 게시됩니다.
  • 결과 : 테스트중인 액터는 메시지를 본 적이 없으며 nerver는 메시지를 전달해야하는 액터로 전달합니다. 전달할 액터가이 테스트에서 메시지가 도착할 것으로 예상되는 테스트 프로브이므로 테스트가 실패합니다.

메시지를 이벤트 스트림에 게시하기 전에 잠들거나 잠깐 기다릴 수는 있지만 배우가 완전히 실행되고 있는지 확인하는 "깨끗한"방법이 아닙니까? 배우가 자신을 완성한 것을 알리는 이벤트 스트림에서 어떤 이벤트를들을 수 있습니까?

@Test 
public void testListenOnEventStreamAndForward() throws InterruptedException 
{ 
    // given 
    final TestProbe actorToForwardMessageTo = new TestProbe(this.actorSystem); 
    final Function<ActorRefFactory, ActorRef> actorToForwardMessageTosFactoryFunction = (actorRefFactory) -> actorToForwardMessageTo.ref(); 
    this.actorSystem.actorOf(Props.create(ActorUnderTest.class,() -> new ActorUnderTest(actorToForwardMessageTosFactoryFunction))); 

    //The test is green, depending on the whether we sleep here or not 
    //Thread.sleep(1000); 

    // when 
    this.eventStream.publish("someStringMessageTheActorUnderTestShouldPickUp"); 

    // then 
    actorToForwardMessageTo.expectMsg("someStringMessageTheActorUnderTestShouldPickUp"); 
} 


private static class ActorUnderTest extends AbstractActor 
{ 

    public ActorUnderTest(final Function<ActorRefFactory, ActorRef> actorToForwardMessageToFactoryFunction) throws Exception 
    { 
     context().system().eventStream().subscribe(self(), String.class); 
     final ActorRef actorToForwardMessageTo = actorToForwardMessageToFactoryFunction.apply(getContext()); 

     receive(ReceiveBuilder 
       .match(
         String.class, 
         stringMessage -> actorToForwardMessageTo.tell(stringMessage, self())) 
       .matchAny(
         message -> unhandled(message)) 
       .build()); 
    } 

} 
+0

테스트에서'resolveOne' 함수를 사용한다면 어떻게 될까요? – rethab

+0

내가 잘못하지 않으면 resolveOne은 actorPath에서 작동합니다. actorRef 만 사용할 수 있습니다. –

답변

관련 문제