我有一个类似于以下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。
答案 0 :(得分:12)
发送给自己的演员非常关注该演员如何执行特定功能的详细信息,因此我宁愿测试该消息的效果,而不是该消息是否已被传递。我认为发送给self与在经典OOP中对象上使用私有帮助器方法相同:你也不测试是否调用了那个,你测试最后是否发生了正确的事情。
作为旁注:您可以实现自己的消息队列类型(请参阅https://doc.akka.io/docs/akka/snapshot/mailboxes.html#creating-your-own-mailbox-type)并允许检查或跟踪消息发送。这种方法的优点在于它可以纯粹通过配置插入到被测试的演员中。
答案 1 :(得分:0)
过去,我已经覆盖了!
的实现,以便我可以添加调试/日志记录。只需打电话给超级!当你完成了,并且要特别注意不要做任何会引发异常的事情。
答案 2 :(得分:0)
我和FSM演员有同样的问题。我尝试按照接受的答案设置自定义邮箱,但几分钟没有让它正常工作。我还尝试按照另一个答案覆盖tell运算符,但这是不可能的,因为self是最终的val。最后我换了:
self ! whatever
使用:
sendToSelf(whatever)
并将该方法添加到actor中:
// 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