【问题标题】:Akka test - wait for actor initializationAkka 测试 - 等待actor初始化
【发布时间】:2020-06-29 19:35:54
【问题描述】:
case class FeatureFilter(s3Client: AmazonS3) extends Actor with ActorLogging {

  override def preStart(): Unit = {
    self ! Initialize
  }

  override def receive: Receive = {
    case Initialize =>
        // long running operaton
        val tryfile = S3Connection(s3Client).downloadObject(...)

          tryfile match {
            case Success(file) =>
                  context.become(active(file))

            case Failure(exception) =>
              self ! PoisonPill
          }
  }
  def active(file: File): Receive = {
    case Query(key) =>
        // do some processing and reply to sender

  }
}

我正在对上述演员使用以下测试:

"an actor" should {
    // mocked S3 client
    val client = ...

    "test for presence of keys" in {

      val actor = system.actorOf(Props(FeatureFilter(client)))

      for (i <- 1 to 100) {
        actor ! Query("test_string")
        expectMsg(SomeMessage)
      }
    }
}

上述测试失败

java.lang.AssertionError: assertion failed: timeout (3 seconds) during expectMsg while waiting ...

我认为这是因为当消息actor ! Query("test_string") 发送给actor 时,它的处理程序仍然是receive,所以它没有响应,因此超时。

但我什至尝试在receive 方法中添加Query(key) 的处理程序(就像在active 方法中一样)。我仍然遇到同样的错误。

  1. 有人能指出这里的问题吗?

  2. 另外,当我将 S3 下载任务移动到 preStart() 时,问题仍然存在。 preStart() 不是阻塞呼叫吗?在完成preStart() 之前,测试中的代码将如何进行?

【问题讨论】:

    标签: scala akka akka-testkit


    【解决方案1】:

    akka stash 听起来像您正在寻找的方式。如果有任何参与者支持但未处理的消息,则添加存储并在达到活动状态时全部取消应用。 查看 actor stash 获取文档和示例用法

    愿你的代码看起来像

    case msg => stash()
    
    ...
    unstashAll()
    context.become(active(file)) 
    

    【讨论】:

      猜你喜欢
      • 2014-09-29
      • 1970-01-01
      • 2019-01-31
      • 2013-02-06
      • 2013-11-27
      • 2019-02-12
      • 2012-05-20
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多