![](/img/trans.png)
[英]MongoDB scala driver: what is a best way to return Future when working with Observer callbacks?
[英]What is the best way to assert for a scala method whose return type is Future[Unit]
我有辦法 此方法可能返回Future.failed(.....)或Future.successful(())。
def compute(x:Int,y:Int):Future [Unit] = {........}
現在,我需要測試此方法。 為驗證Future.successful(())
case的測試斷言的最佳方法是什么?
Scalatest提供了使用Future
的幾種方法。
選項1: isReadyWithin
import org.scalatest.concurrent.ScalaFutures._
import scala.concurrent.duration._
calculate(1, 3).isReadyWithin(1.second) should be(true)
如果您想在此處做一些返回值的操作,則可以使用whenReady
:
implicit val patienceConfig = PatienceConfig(1.second)
def calculateWithResult(i: Int, j: Int): Future[Int] = ???
whenReady(calculateWithResult(1,3)) { result =>
result should be(4)
}
您需要在作用域中隱式的PatienceConfig
來告知whenReady
何時由於超時而導致測試失敗。 我相信在一個scalatest
庫中有一個默認庫,但是選擇的時間段很短-大約10毫秒-經常會導致不穩定的測試。
選項2: AsyncXSpec
有FlatSpec
, FreeSpec
, FunSpec
等特性的Async
變體。 它們的工作方式與它們的同步變體一樣,除了現在任何測試必須返回類型為Future[Assertion]
。 例如:
class Test extends AsyncFreeSpec {
"An asynchronous method" - {
"should succeed" in {
calculate(1,3).map { _ =>
// just want to make sure the future completes
succeed
}
}
}
}
同樣,您可以在此處針對結果進行測試。 請注意,此變體意味着測試類中的每個測試都必須返回Future
,因此如果您要混合使用同步測試和異步測試,那就不好了。 老實說,我也不確定AsyncXSpec
如何選擇其超時值。
選項不要: Await.result
我建議不要使用Await.result
因為它會在一段時間內阻塞線程。 據我所知,以上兩個選項的設計目的是使異步測試可以輕松地並行運行。
注意事項:
在進行異步測試時,您要非常小心超時。 太長的時間,如果出了點問題,您的測試可能會持續很長時間。 太短了,您的測試將變得不穩定。 而且該程序在不同的環境中可能會執行不同的操作,因此您可能會發現,在本地計算機上完全足夠的超時會使構建服務器上的測試失敗5%。 小心!
至少有兩個選擇:
Await.result
,然后通過斷言某些內容來確保結果與預期的一樣。 AsyncFlatSpec
東西。 我假設您已經在測試類中擴展了ScalaFutures
,並且已根據需要配置了timeout( patienceConfig
)。 如果這樣做,則可以使用以下方法之一:
whenReady(calculate(1,3))(_ => succeed)
要么
whenReady(calculate(1,3))(_ shouldBe ())
第一種方法比較可取,因為Unit
不能有任何其他值,因此我們不必顯式檢查它,除非代碼由於某種原因返回null
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.