2016-08-04 3 views
4

메시지를받을 때마다 응답으로 응답하도록 테스트 프로브를 얻으려고합니다. Akka Actor Test : TestProbe를 사용한 자동 응답

나는 내 테스트에 다음 코드를 작성했지만 작동하지 않습니다

val chgtWriter = new TestProbe(system) { 

      def receive: Receive = { 

      case m => println("receive messagereplying with ACK"); sender() ! ACK 

      } 

     } 

이 할 수있는 방법이 있나요. 실제로 테스트 프로브에 메시지를 보내는 액터는 TestThread가 아닌 다른 스레드에서 실행 중입니다. 아래에서 현재 작성된 전체 테스트를 볼 수 있습니다.

feature("The changeSetActor periodically fetch new change set following a schedule") { 


scenario("A ChangeSetActor fetch new changeset from a Fetcher Actor that return a full and an empty ChangeSet"){ 


    Given("a ChangeSetActor with a schedule of fetching a message every 10 seconds, a ChangeFetcher and a ChangeWriter") 

    val chgtFetcher = TestProbe() 

    val chgtWriter = new TestProbe(system) { 

     def receive: Receive = { 

     case m => println("receive message {} replying with ACK"); sender() ! ACK 

     } 

    } 
    val fromTime = Instant.now().truncatedTo(ChronoUnit.SECONDS) 
    val chgtActor = system.actorOf(ChangeSetActor.props(chgtWriter.ref, chgtFetcher.ref, fromTime)) 

    When("all are started") 


    Then("The Change Fetcher should receive at least 3 messages from the ChangeSetActor within 40 seconds") 

    var changesetSNum = 1 

    val received = chgtFetcher.receiveWhile(40 seconds) { 

     case FetchNewChangeSet(m) => { 

     println(s"received: FetchNewChangeSet(${m}") 

     if (changesetSNum == 1) { 
      chgtFetcher.reply(NewChangeSet(changeSet1)) 
      changesetSNum += 1 
      } 
      else 
      chgtFetcher.reply(NoAvailableChangeSet) 
     } 

     } 

    received.size should be (3) 

} 

}

changeSetActor가 완벽하게 테스트 및 작동합니다. 이 테스트는 ChangeWriter를 사용하여 중단됩니다. receive 메소드에서 메시지를 수신하지 않습니다.

EDIT1 (다음 @Jakko의 답변)

Auto Pilots은 다음과 같다 : 지금까지 주어진 모든 설명이 방법은 분명하지만

의에서 혼란 무엇
val probe = TestProbe() 
probe.setAutoPilot(new TestActor.AutoPilot { 
    def run(sender: ActorRef, msg: Any): TestActor.AutoPilot = 
    msg match { 
     case "stop" ⇒ TestActor.NoAutoPilot 
     case x  ⇒ **testActor.tell(x, sender)**; TestActor.KeepRunning 
    } 
}) 

입니다 공식적인 예는 참조 "testActor"입니다. 여기 검사 검사는 누구입니까? 그 시점에서 그 이름의 변수 선언은 없습니다.

답변

3

Auto Pilots을 사용하여 테스트 프로브를 스크립팅 할 수 있습니다. 예 :

import akka.testkit._ 
val probe = TestProbe() 
probe.setAutoPilot(new TestActor.AutoPilot { 
    def run(sender: ActorRef, msg: Any): TestActor.AutoPilot = { 
    println("receive messagereplying with ACK") 
    sender ! ACK 
    TestActor.KeepRunning 
    } 
}) 

위 예제에서 자동 메시지 처리기 인 자동 파일럿으로 테스트 프로브를 설정합니다. 프로브가 메시지를 수신하면 자동 조종 장치가 자동으로 트리거됩니다. 이 예에서 자동 조종사는 메시지를 인쇄하고 발신자에게 다시 응답합니다.

메시지를 처리 ​​한 후 자동 파일럿이 다음 들어오는 메시지의 처리 방법을 결정할 수 있습니다. 다른 자동 파일럿을 설정하거나 기존 자동 파일럿 (TestActor.KeepRunning)을 재사용하거나 자동 파일럿을 완전히 비활성화 할 수 있습니다 (TestActor.NoAutoPilot). 이 예에서는 동일한 자동 파일럿이 모든 수신 메시지를 처리하는 데 사용됩니다.

프로브에 부착 된 자동 조종 장치가있는 경우에도 평소대로 테스트 프로브 어설 션을 계속 사용할 수 있습니다.

공식 문서에있는 testActor은 테스트를 작성중인 배우를 나타냅니다. 예를 들어, 귀하의 경우 액터는 chgtActor에 할당 된 ChangeSetActor 일 수 있습니다. 실제로 원하는 것은 프로브에서 발신자에게 응답하는 것이므로 테스트 프로브 자동 파일럿이 발신자에게 다시 응답하고 testActor을 신경 쓰지 않아도됩니다.

+0

'KeepRunning' 누락 및 누락 된 부분을 추가했습니다. –

+0

원본 게시글에 주석을 달 수있는 대리인이 충분하지 않으므로 여기에 내 의견을 추가하겠습니다. 'target.tell (message, source)'는 거의'target! message' : 둘 다'target '에 메시지를 보낸다. 차이점은 메시지 송신자를'.tell()'으로 명시 적으로 지정해야하지만,'! '로 지정하면 송신자가 암시 적으로 선택됩니다. 액터 내에서'! '를 호출하면 액터가 보낸 사람으로 사용됩니다. –

+0

답변에서 업데이트로 질문을 편집했습니다. 나는 여기서 당신이 보낸 사람을 사용하는 이유는 무엇입니까? testActor.tell (ACK, 보낸 사람) 대신 ACK.나는 원래의 예제에서 testActor가 나타내는 변수가 무엇인지 알지 못합니다. 가장 중요한 것은 어디에 정의되어 있는지입니다. – MaatDeamon

관련 문제