2017-08-03 70 views
0

我想用AkkaTestKit测试我的演员逻辑。问题是我的演员使用ask模式。所以我需要以某种方式回答。它看起来像这样:回答AkkaTestKit

case class AskExecution(id: Long) 

    override def receive: Receive = { 
    case id : Long => 
     implicit val dispatcher = context.dispatcher 
     implicit val timeout = Timeout(10 seconds) 
     val executor = sender 

     //How to answer this? 
     val f = executor ? AskExecution(id) map(v => v.asInstanceOf[Option[Long]]) 
     f.onComplete{ 
     case Success(k) => 
     case Failure(_) => 
     } 
    } 

在测试中,我使用它,如下所示:

val ca = TestActorRef(new TheActor()) 
ca ! 0L //I send 0, Now I want to answer the ask 
     //How to do so? 

回答

1

为了使你的代码更易于测试,给你的演员执行人演员的参考(处理该演员消息)。

import akka.pattern.pipe 

class TheActor(executor: ActorRef) extends Actor { 
    def receive = { 
    case id: Long => 
     val s = sender 
     implicit val dispatcher = context.dispatcher 
     implicit val timeout = 10.seconds 
     (executor ? AskExecution(id)).mapTo[Option[Long]].pipeTo(s) 
} 

class Executor extends Actor { 
    def receive = { 
    case AskExecution(id) => 
     // do something to get a result 
     val result: Option[Long] = ??? 
     sender ! result 
    } 
} 

test,假设你的测试类扩展TestKit并在ImplicitSender特质混合物:

val executor = system.actorOf(Props[Executor]) 
val theActor = system.actorOf(Props(classOf[TheActor], executor)) 

within(10.seconds) { 
    theActor ! 0L 
    expectMsgClass(classOf[Option[Long]]) 
} 

// test the executor directly 
within(10.seconds) { 
    executor ! AskExecution(3L) 
    expectMsgClass(classOf[Option[Long]]) 
} 
+0

它注入了'TestProbe',并用它来验证消息已发送和回应更简单给他们。不需要创建一个新的演员类,如果其他演员的行为取决于状态,则特别有用。 –