12

我有一个在功能上类似于以下 Actor 的 Actor。

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 消息在测试中发送给 self?

我正在使用 scalatest 2.0.M4、Akka 2.0.3 和 Scala 1.9.2。

4

3 回答 3

15

发送给自己的参与者是该参与者如何执行特定功能的非常私密的细节,因此我宁愿测试该消息的效果,也不愿测试该消息是否已传递。我认为发送给 self 与在经典 OOP 中对对象使用私有辅助方法相同:您也不测试是否调用了该方法,而是测试最终是否发生了正确的事情。

作为旁注:您可以实现自己的消息队列类型(请参阅https://doc.akka.io/docs/akka/snapshot/mailboxes.html#creating-your-own-mailbox-type)并允许检查或跟踪消息发送。这种方法的美妙之处在于它可以纯粹通过配置插入到被测参与者中。

于 2012-09-19T09:04:10.097 回答
0

过去,我已经覆盖了实现,!以便我可以添加调试/日志记录。就叫超级吧!完成后,请格外小心,不要做任何会引发异常的事情。

于 2012-09-18T20:38:50.543 回答
0

我对 FSM 演员也有同样的问题。我尝试根据接受的答案设置自定义邮箱,但几分钟后无法正常工作。我还尝试根据另一个答案覆盖告诉运算符,但这是不可能的,因为 self 是最终值。最终我只是更换了:

 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
于 2014-11-19T21:04:39.003 回答