Подтвердить что ты не робот

Как можно проверять сообщения, отправленные на себя, доставляются при тестировании аккских актеров?

У меня есть Актер, который похож на следующий Актер в функции.

case class SupervisingActor() extends Actor {

    protected val processRouter = //round robin router to remote workers
    override def receive = {
        case StartProcessing => { //sent from main or someplace else
            for (some specified number of process actions ){
                processRouter ! WorkInstructions
            }
        }
        case ProcessResults(resultDetails) => {  //sent from the remote workers when they complete their work
            //do something with the results
            if(all of the results have been received){
                //*********************
                self ! EndProcess  //This is the line in question
                //*********************
            }
        }
        case EndProcess {
            //do some reporting
            //shutdown the ActorSystem
        }
    }
}

}

Как я могу проверить, что сообщение EndProcess отправлено самому себе в тесте?

Я использую scalatest 2.0.M4, Akka 2.0.3 и Scala 1.9.2.

4b9b3361

Ответ 1

Актер, отправляющий сам по себе, представляет собой очень подробную информацию о том, как этот актер выполняет определенную функцию, поэтому я предпочел бы проверить эффект этого сообщения, чем то, было ли это сообщение доставлено. Id утверждают, что отправка в себя - это то же самое, что и частный метод-помощник на объекте в классическом ООП: вы также не проверяете, вызван ли этот вызов, вы проверяете, произошло ли в конечном итоге.

В качестве побочного примечания: вы можете реализовать свой собственный тип очереди сообщений (см. https://doc.akka.io/docs/akka/snapshot/mailboxes.html#creating-your-own-mailbox-type) и иметь возможность проверки или отслеживания отправки сообщений. Красота этого подхода заключается в том, что он может быть вставлен исключительно по конфигурации в тестируемый актер.

Ответ 2

В прошлом я переопределил реализацию для !, чтобы добавить debug/logging. Просто позвоните супер! когда вы закончите, и будьте осторожны, чтобы не делать ничего, что могло бы вызвать исключение.

Ответ 3

У меня была такая же проблема с актером FSM. Я попытался настроить пользовательский почтовый ящик в соответствии с принятым ответом, но через несколько минут он не работал. Я также попытался переопределить оператор tell в соответствии с другим ответом, но это невозможно, так как self является окончательным значением val. В конце концов я просто заменил:

 self ! whatever

с:

 sendToSelf(whatever)

и добавил этот метод в актер как:

// test can override this
protected def sendToSelf(msg: Any) {
  self ! msg
}

то в тесте переопределите метод для захвата сообщения, отправленного самостоятельно, и отправим его обратно в fsm для завершения работы:

  @transient var sent: Seq[Any] = Seq.empty

  val fsm = TestFSMRef(new MyActor(x,yz) {
    override def sendToSelf(msg: Any) {
      sent = sent :+ msg
    }
  })

  // yes this is clunky but it works
  var wait = 100
  while( sent.isEmpty && wait > 0 ){
    Thread.sleep(10)
    wait = wait - 10
  }

  fsm ! sent.head