2014-11-03 37 views
1

我是在akka系统上使用scala的新手。小孩在akka上的测试回复

我有一位父母演员(名字叫“经理”),向孩子发送消息,并接收一个答案,并将答案转发给下一个孩子。 最后的演员保存整个过程的结果。

我想创建一个将消息发送给父(“管理器”)的端到端测试,并期望来自最后一个接收结果的actor的消息。 我正在寻找一种简单的方法来指导最终演员发送消息回测试。由于测试不是发件人,也不是简单的演员,我不知道如何正确引导信息。

以下是测试代码:

class EndToEndTest extends TestKit(ActorSystem("MyActorSystem")) 
with FunSuiteLike with Matchers with BeforeAndAfterAll with ImplicitSender { 

    override def afterAll { 
     TestKit.shutdownActorSystem(system) 
    } 

    test("should send result") { 

    val actor = system.actorOf(Props(new Manager(name = "ActorManager"))) 
    actor ! tPoint(1000L) 
    actor ! tPoint(2000L) 

    expectMsg(ActorResult(1)) 
    } 
} 

最后一个儿童演员和:

class SensorHealthReportMySqlActor extends Actor with ActorLogging { 

    def receive = { 
     case Result(result: Long) => 

     //this is where i would like to send the test a message with Result(result) 

     case _ => 
      log.error("Unknown message type") 
    } 

} 

任何帮助,将不胜感激。

回答

2

我认为你想要的解决方案是通过一个ActorRef作为消息中的参数,因此当消息应发送给除当前消息的发送者以外的某个参与者时,接收者知道应该发送答复的位置。

因此就沿着这些线路:

import akka.actor.{Actor, Props, ActorRef, ActorLogging} 

case class tPoint(n: Long) 
case class Result(result: Long, replyTo: ActorRef) 
case class ActorResult(result: Long) 

class Manager(name: String) extends Actor { 

    val child = context.actorOf(Props(new SensorHealthReportMySqlActor)) 

    override def receive: Receive = { 
    case msg: tPoint ⇒ 
     child ! Result(msg.n, sender()) 
    } 
} 



class SensorHealthReportMySqlActor extends Actor with ActorLogging { 

    def receive = { 
    case Result(result: Long, replyTo: ActorRef) => 
     //this is where i would like to send the test a message with Result(result) 
     replyTo ! ActorResult(1) 

    case _ => 
     log.error("Unknown message type") 
    } 

} 

在这种情况下,sender()Managerreceive方法是测试本身,这是一个ImplicitSender(如你在测试中声明)。这是一个可以接收消息的幕后创建的演员。

在非测试系统中,您可以使用ask模式或Inbox来达到同样的目的。请参阅文档Actors