簡體   English   中英

對返回類型為Future [Unit]的scala方法進行斷言的最佳方法是什么

[英]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

FlatSpecFreeSpecFunSpec等特性的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM