如何根据ActorSelection模拟一个actor?

Raf*_*eco 3 java testing actor akka akka-testkit

我已经搜索了很多关于这一点,但没有答案.

我有一个演员"A" (用户/ A),当收到消息"M"时,它为另一个演员"B" (用户/ B)发送消息"X ".为此,演员A使用ActorSelection我需要测试当我将M发送给A时,B将接收"X".

我尝试在"user/B"上使用TestProbe执行此操作,但没有成功.

我也看到了一些类似的问题,但每个答案都说使用了ActorRef的ActorRef.这不是我的选择,我真的需要使用ActorSelection.

有人有点想法吗?

Rol*_*uhn 6

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

  • 您不需要控制名称,因为您可以从`probe.ref.path`获取它. (2认同)

Mic*_*hta 5

您可以为测试编写简单的帮助程序,这些帮助程序的名称与您的actor类似,但会将消息转发给您的探针

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

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

你想测试演员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)
Run Code Online (Sandbox Code Playgroud)

然后你就可以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
}
Run Code Online (Sandbox Code Playgroud)