2013-10-07 78 views
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已經發送之後纔開始。我怎麼解決這個問題?

回答

1

是不是你想要將探測器傳遞給控制器​​而不是虛擬角色的實現,如果不是,將如何發送到探測器?

+0

你是對的。更改代碼以使用探針而不是特殊演員時,我犯了一個錯誤。虛擬演員甚至不需要。測試現在可以使用。我想接受你的回答,但如果你能提供更多解釋爲什麼這會起作用,那將是非常好的。對於doStuff的調用實際上是異步運行的,不像我在問題中所說的那樣?如果msg很快發送,此測試可能會失敗嗎?謝謝。 – mushroom

+0

就我對Akka測試庫的理解而言,我認爲它會運行一個在調用線程上執行的調度程序的actor系統,因此使用「actor!message」發送將實際上阻塞並返回一個完整的未來。 – johanandren

+0

第二個想法我只注意到,你的測試不使用akka測試的東西(TestBase等),但只有探針。所以爲了修改這個答案,我認爲probe.expectMessage將會阻塞一個默認的超時時間,如果這個消息還沒有到達,那麼就會失敗。如果需要,您可以指定不同的超時值。 – johanandren