0
我的打法應用程序使用阿卡演員來處理長期運行的計算:測試播放器的交互與阿卡演員
class MyController(myActor : ActorRef) extends Controller{
def doStuff = Action { implicit request =>
val response : Future[Any] = myActor ? DoStuff
Async{
response.map{
str : String => Ok(str)
}
}
}
}
我試圖測試一切是否正常工作。我有單獨的測試來檢查演員的行爲是否正確,並且大多隻是想檢查控制器是否將正確的消息發送給演員。我目前的方法是這樣的:
class MyControllerSpec extends Specification{
"MyController" should {
object DummyActor extends Actor{
def receive = {
case _ =>()
}
}
"do stuff properly" >> {
val probe = TestProbe()(Akka.system)
val test = new controllers.MyController(Akka.system.actorOf(Props(DummyActor))
val result = test.doStuff(FakeRequest())
probe.expectMsg(SomeMsg)
}
}
}
當調用doStuff動作時,控制器會向傳入的actor發送消息。我正在嘗試驗證是否發送了正確的消息。
我認爲test.doStuff是同步運行的,並在虛擬actor不發送任何東西時超時。 expectMsg在doStuff調用返回並且SomeMsg已經發送之後纔開始。我怎麼解決這個問題?
你是對的。更改代碼以使用探針而不是特殊演員時,我犯了一個錯誤。虛擬演員甚至不需要。測試現在可以使用。我想接受你的回答,但如果你能提供更多解釋爲什麼這會起作用,那將是非常好的。對於doStuff的調用實際上是異步運行的,不像我在問題中所說的那樣?如果msg很快發送,此測試可能會失敗嗎?謝謝。 – mushroom
就我對Akka測試庫的理解而言,我認爲它會運行一個在調用線程上執行的調度程序的actor系統,因此使用「actor!message」發送將實際上阻塞並返回一個完整的未來。 – johanandren
第二個想法我只注意到,你的測試不使用akka測試的東西(TestBase等),但只有探針。所以爲了修改這個答案,我認爲probe.expectMessage將會阻塞一個默認的超時時間,如果這個消息還沒有到達,那麼就會失敗。如果需要,您可以指定不同的超時值。 – johanandren