Akka演员测试:使用TestProbe自动回复

时间:2016-08-04 22:23:08

标签: scala akka actor akka-testkit

每当收到任何消息时,我都会尝试让测试探针回复确认。

我在测试中编写了以下代码,但它不起作用:

val chgtWriter = new TestProbe(system)  {

          def receive: Receive = {

            case m => println("receive messagereplying with ACK"); sender() ! ACK

          }

        }

有没有办法做到这一点。实际上将消息发送到测试探针的actor肯定在另一个线程上运行,而不是TestThread。您可以在下面看到当前制作的完整测试。

feature("The changeSetActor periodically fetch new change set following a schedule") {


scenario("A ChangeSetActor fetch new changeset from a Fetcher Actor that return a full and an empty ChangeSet"){


  Given("a ChangeSetActor with a schedule of fetching a message every 10 seconds, a ChangeFetcher and a ChangeWriter")

    val chgtFetcher = TestProbe()

    val chgtWriter = new TestProbe(system)  {

      def receive: Receive = {

        case m => println("receive message {} replying with ACK"); sender() ! ACK

      }

    }
    val fromTime = Instant.now().truncatedTo(ChronoUnit.SECONDS)
    val chgtActor = system.actorOf(ChangeSetActor.props(chgtWriter.ref, chgtFetcher.ref, fromTime))

  When("all are started")


  Then("The Change Fetcher should receive at least 3 messages from the ChangeSetActor within 40 seconds")

    var changesetSNum = 1

    val received = chgtFetcher.receiveWhile( 40 seconds) {

      case FetchNewChangeSet(m) => {

        println(s"received: FetchNewChangeSet(${m}")

        if (changesetSNum == 1) {
            chgtFetcher.reply(NewChangeSet(changeSet1))
            changesetSNum += 1
          }
          else
            chgtFetcher.reply(NoAvailableChangeSet)
        }

      }

    received.size should be (3)

}

}

changeSetActor经过全面测试并正常运行。测试与ChangeWriter挂起。它永远不会在receive方法中收到消息。

EDIT1(关注@Jakko anser)

Auto Pilots如下:

val probe = TestProbe()
probe.setAutoPilot(new TestActor.AutoPilot {
  def run(sender: ActorRef, msg: Any): TestActor.AutoPilot =
    msg match {
      case "stop" ⇒ TestActor.NoAutoPilot
      case x      ⇒ **testActor.tell(x, sender)**; TestActor.KeepRunning
    }
})

虽然到目前为止给出的所有解释都很明确,但官方例子中令人困惑的是参考" testActor"。谁是testActor?那时没有该名称的变量声明。

1 个答案:

答案 0 :(得分:6)

您可以使用Auto Pilots编写测试探针的脚本。例如:

import akka.testkit._
val probe = TestProbe()
probe.setAutoPilot(new TestActor.AutoPilot {
  def run(sender: ActorRef, msg: Any): TestActor.AutoPilot = {
    println("receive messagereplying with ACK")
    sender ! ACK
    TestActor.KeepRunning
  }
})

在上面的示例中,我们使用自动消息处理程序Auto Pilot设置了一个测试探针。当探针收到消息时,将自动触发自动导航。在此示例中,自动驾驶仪将打印一条消息并回复给发件人。

在处理完消息后,自动驾驶员可以决定如何处理下一个传入消息。它可以设置不同的自动导航,重用现有的自动导航(TestActor.KeepRunning),也可以完全禁用自动导航(TestActor.NoAutoPilot)。在此示例中,将使用相同的自动导航来处理所有传入消息。

即使将自动导航器连接到探头上,您仍然可以照常使用测试探头断言。

官方文档中的testActor指的是您正在编写测试的actor。例如,在您的情况下,参与者可以是ChangeSetActor分配给值chgtActor。由于您真正想做的就是通过探测回复发件人,因此测试探针自动驾驶员可以回复发件人而不关心testActor