我正在使用Akka經典角色(在Play框架中運行),在sender()方法上遇到了一個問題。當我構建并運行代碼時(使用sbt run),我可以看到sender()決議到deadLetters角色。然而,當運行該角色的單元測驗時,sender()決議到了正確的 ActorRef(盡管它不應該)。
sender()是在一個關閉的未來中被呼叫的,這就是為什么我在運行實際實作時看到了deadLetters。然而,由于某些原因,我在單元測驗中沒有看到deadLetters。有什么想法嗎?為什么單元測驗和運行實體之間的行為會有差異?
一些示例代碼,讓大家了解代碼結構
class MyActor extends Actor{
private def throwError()= {
// THIS IS WHERE sender() BEHAVIOR DIFFERENTIATE BETWEEN IMPLEMENTATION AND UNITTESTS.
sender() ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType)。Future[Done] = {
for {
Some logic here...
} yield {
if (一些邏輯檢查...)
throwError()
else[/span
完成。
}
}
override def stepReceive= {
case MyMessage(args)=>
myFutureMethod(args)
}
}
一些示例代碼,讓我們了解unittest的結構
。 "My failure test case" in {
val testProbe = TestProbe()
myActorImpl.tell(MyMessage(args), testProbe)
//testProbe應該不會收到上面的訊息。
// 執行,但它確實如此。
testProbe.expectNoMessage()
}
如果有人有一些除錯的技巧或想法,那就太好了。謝謝。
uj5u.com熱心網友回復:
在行為體中作為Future的一部分執行的代碼中呼叫sender是不確定的(即一個競賽條件),因為你的MyActor可以在Future中的代碼執行之前繼續處理另一個訊息,如果它從那時起已經執行,sender將已經改變,可能是deadLetters。
在您的測驗中,如果myActorImpl還沒有處理一個訊息,sender將仍然指向測驗探針。
假設你希望訊息真的被發送到發送者那里,你需要在把它交給Future之前捕獲它,按照這樣的思路
class MyActor extends Actor{
private def throwError(target: ActorRef) = {
//使用捕獲的發送者,沒有競賽條件。
target ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType, sender: ActorRef)。) Future[Done] = {
for {
Some logic here...
} yield {
if (一些邏輯檢查...)
throwError(sender)
else[/span
完成。
}
}
override def stepReceive= {
case MyMessage(args)=>
myFutureMethod(args, sender) //捕捉到sender的參考。
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/309087.html
標籤:
下一篇:只獲取超類欄位
