2016-03-02 79 views
1

我使用帶有Spray和WireMock的Akka actor系統來存儲Web服務。我也想驗證外部http請求已經完成。使用WireMock測試異步行爲

在下列情況下使用POST請求被我噴服務器提出應該將請求發送到外部服務:

stubFor(get(urlEqualTo("/external-service")) 
    .willReturn(aResponse() 
     .withStatus(200) 
     .withBodyFile("response-body.json"))); 

myService ! Post("/my-service", FormData(Seq("id" -> "1"))) 

Thread.sleep(1000) 

verify(postRequestedFor(urlEqualTo("/services/harvesterService"))) 

在我見過的Thread.sleep技術各種例子,因爲否則的話ActorSystem被關閉,我的服務永遠不會爲外部服務發起http請求。

可以避免這種情況嗎? WireMock能否等待對外部服務的請求?可能有一些超時...

回答

1

注意:這假定您的演員實際上發送一個HTTP調用,當它收到該消息。如果你想直接測試噴霧路線,我建議你看看http://spray.io/documentation/1.2.3/spray-testkit/這是測試噴霧路線的標準方法。

通常我會將ScalaTest與Akka/Spray TestKit一起使用,並使用eventually函數。 eventually允許您重複檢查最終會發生的情況。如果您發現verify方法引發的異常,那麼您可以聲明帖子實際上是否已發送。您可以使用類似

def postHasBeenSent(url: String): Boolean = 
    try { 
    verify(postRequestedFor(urlEqualTo(url))) 
    true 
    } catch { 
    case e: VerificationException => false 
    } 

(你也可以使用Try單子,如果你想有,但這裏不是重點!)

然後在您的測試(假設你使用的匹配):

myService ! Post("/my-service", FormData(Seq("id" -> "1"))) 

eventually { 
    postHasBeenSent("/my-service") shouldBe true 
} 

你可以找到http://doc.scalatest.org/2.2.6/index.html#org.scalatest.concurrent.Eventually

更多 eventually和所有隨之而來(例如輪詢間隔)的好東西