3

我对此进行了很多搜索,但没有答案。

我有一个演员“A” (用户/A )在收到消息“M”时为另一个演员“B” (用户/B)发送消息“X” 。为此,演员 A 使用ActorSelection我需要测试当我将M发送到A时,B将收到“X”。

我尝试在“用户/B”上使用 TestProbe 执行此操作,但没有成功。

我也看到了一些类似的问题,但每个答案都说使用 ActorRef insted of ActorSelection。这对我来说不是一个选项,我真的需要使用 ActorSelection。

有人有什么想法吗?

4

2 回答 2

6

简单的答案:不是在 A 中硬编码选择的路径,而是使其可配置。在测试中,您可以将其指向 TestProbe 的路径。

于 2015-09-14T05:36:58.100 回答
5

您可以为您的测试编写简单的助手,这些助手的名称与您的演员相似,但会将消息转发给您的探测器。

假设这是您的设置(简化):

case object M
case object X
class A extends Actor {
  def receive = {
    case M => context.system.actorSelection("/user/B") ! X
  }
}

你想测试 actor A

您可以为您的应用编写这种“测试框架”:

object ForwardActor {
  def props(to: ActorRef) = Props(new ForwardActor(to))
}

class ForwardActor(to: ActorRef) extends Actor {
  override def receive = {
    case x => to forward x
  }
}

def mock(name: String, probe: TestProbe)(implicit system: ActorSystem): Unit = 
  system.actorOf(ForwardActor.props(probe.ref), name)

然后你就可以A通过简单地做这种测试来测试actor:

"A sends X to B after receiving M" in {
  val probeB = TestProbe()
  mock("B", probeB)
  system.actorOf(Props(new A)) ! M
  probeB expectMsg X
}
于 2015-09-14T08:24:32.403 回答