Акка тест - дождаться инициализации актера - PullRequest
0 голосов
/ 18 марта 2020
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: утверждение не выполнено: тайм-аут (3 секунды) во время ожидаемого ожидания во время ожидания ...

Я думаю, это потому, что когда сообщение actor ! Query("test_string") отправляется актеру, его обработчик все еще receive, и поэтому он не ответить, а значит и тайм-аут.

Но я даже попытался добавить обработчик для Query(key) в методе receive (как в методе active). Тем не менее я получаю ту же ошибку.

  1. Может кто-нибудь указать, в чем здесь проблема?

  2. Также, когда я перемещаю задачу загрузки S3 до preStart(), проблема остается прежней. Разве preStart() не является ли блокирующим вызовом? Как будет действовать код в тесте, пока preStart() не будет завершено?

1 Ответ

0 голосов
/ 13 апреля 2020

akka sta sh звучит так, как вы ищете. В случае любого сообщения, которое поддерживает актер, но не обрабатывается, добавьте на sta sh и отмените все, если активен достигнут. посмотрите документацию и пример использования actor sta sh

, возможно, ваш код будет выглядеть как

case msg => stash()

...
unstashAll()
context.become(active(file)) 
...