2016-06-12 60 views
2

我有一個請求,其響應取決於actor的回覆。我想測試一下這種方式:Akka-Http:How to TestProbe請求

val myActor:TestProbe = TestProbe() 

val route = new MyRoute() { 
    override def myServiceActor:ActorRef = { 
     myActor.ref 
    } 
}.route 

"return a query result for GET" in { 
    Get("/foo") ~> route ~> check { 
     myActor.expectMsg(ExecuteFoo()) 
     myActor.reply(FOO) 
     responseEntity shouldEqual toJsonEntity(RequestResult(FOO)) 
    } 
} 

我得到正確的是expectMsg驗證,但reply是對responseEntity檢查異步尊重。在這種情況下,測試失敗。

有沒有辦法等待答覆?

回答

3

您正在使用TestProbe正確的方向。關鍵是將運行請求的組合分開,然後通過check將其作爲1步完成兩個明確的步驟。首先運行它,然後在TestProbe上做任何瑕疵,最後進行檢查。爲您的樣品更新的代碼應該是這樣的:

val result = Get("/foo") ~> route ~> runRoute 
    myActor.expectMsg(ExecuteFoo()) 
    myActor.reply(FOO) 

    check { 
     responseEntity shouldEqual toJsonEntity(RequestResult(FOO)) 
    }(result) 

你可以看到那裏,我第一次使用runRoute簡單的運行路線沒有進行任何檢查。我將此值分配給result,因爲稍後我需要執行任何檢查。然後,您可以安全地對TestProbe進行剔除。此時,它已收到該消息,正在等待您的電話以驗證它收到了什麼消息以及如何響應。然後,完成後,我們可以調用check,將顯式結果(從runRoute開始)傳遞給該調用,而不是依賴隱式。

如果您遵循此方法,您應該能夠正確測試呼叫演員的路線,並使用TestProbe這樣做。

+0

喜歡它!謝謝!結果的一種「產量」擺脫了異步問題:) – Randomize

0

這樣做的一種方法(可能不是正確的或唯一的一種)使用AutoPilot。以下是一個示例:

val myProbe = TestProbe() 
myProbe.setAutoPilot(new TestActor.AutoPilot { 
    def run(sender: ActorRef, msg: Any) = msg match { 
    case ExecuteFoo(_) => 
     //do something else if needed 
     sender ! FOO 
     TestActor.NoAutoPilot 
    } 
}) 
+0

有趣的謝謝你。到目前爲止,我嘗試使用receive方法創建一個模擬並且工作正常。但我不確定它是否會引入一些間歇性測試。 – Randomize