3.3 两路消息

我们已经在对 SendingActor 风格的 actor 的多线程测试中看到了两路消息的例子, 那里我们使用包含 ActorRef 的 GetState 消息 我们简单地在 ActorRef 上调用 ! 操作符来响应 GetState 请求。 像之前展示的, tell 方法包含一个隐式的发送者的引用。

两路消息非常容易以黑盒的方式测试,一个请求引起一个回应,对于回应可以用断言。 在下边的测试用,我们测试 EchoActor,这是一个回应重复任何请求的 actor。

Listing 3.16 测试 Echoes

"Reply with the same message it receives without ask" in {
  val echo = system.actorOf(Props[EchoActor], "echo2")
  echo.tell("some message", testActor)
  expectMsg("some message")
}
  1. 调用 tell, 把 testActor 作为发送者
  2. 像平常一样断言消息

我们用一个显式的发送者作为参数调用 tell 方法,EchoActor 会用它来把回应发回。 EchoActor 与之前完全一样,只是把消息发送回发送者。

Listing 3.17 Echo Actor

class EchoActor extends Actor {
  def receive = {
    case msg =>
      sender ! msg
  }
}

无论使用 ask 模式,还是 tell 方法,EchoActor 的反应都是完全一样的;上边是测试两路消息较好的方法。

本节中的主要行程是走一遍 Akka 的 TestKit 提供的 actor 测试的习惯做法。 他们都是为同一个目的服务:使得编写需要访问结果的单元测试更简单,其中单元测试对结果进行断言。 测试工具箱同时为单线程和多线程测试提供了方法。 我们甚至可以稍稍欺骗,在测试中获取底层的 actor 实例。 根据如何与其他 actor 交互,对 actor 进行分类,给我们提供了如何测试 actor 的模板,我们展示了 SilentActor, SendingActor, 和 SilentActor 三种类型。 在大多数情况下,测试 actor 最简单的办法是传递 testActor 的引用给它,可以用这个引用来断言对测试中 actor 发出消息的预期。 testActor 可以用来在对请求的回应中代替发送者,或者可以表现地像可以发送消息给它的下一个 actor, 最后,我们看到在一些情况下,让 actor 准备好测试,特别是这个 actor 是”静默“的,是很有意义的。如果 actor 是“静默”的,给 actor 加一个监听器很有用。