[英]Unit testing strategy in Scala with Try, Success, Failure
為了簡單起見,假設我們有一個名為listTail
的方法,該方法以以下方式定義:
private def listTail(ls: List[Int]): List[Int] = {
ls.tail
}
我們還有一個方法可以在列表為空時處理異常。
private def handleEmptyList(ls: List[Int]): List[Int] = {
if(ls.isEmpty) List.empty[Int]
}
現在,我想創建一個安全版本的listTail
方法,該方法同時使用兩種方法:
import scala.util.{Try, Success, Failure}
def safeListTail(ls: List[Int]): List[Int] = {
val tryTail: Try[List[Int]] = Try(listTail(ls))
tryTail match {
case Success(list) => list
case Failure(_) => handleEmptyList(ls)
}
}
我的問題是,如果兩個私有方法都已經過測試,那么我也應該測試安全方法嗎? 如果是的話,怎么辦? 我當時只是想檢查是否根據輸入內容執行了模式匹配案例。 也就是說,當我們遇到“失敗”情況時,將執行handleEmptyList
方法。 但是我現在知道如何檢查這一點。
還是我需要重構代碼,並將所有內容放在一個方法中? 即使也許我的私有方法比示例中的復雜得多。
我的測試是使用ScalaTest編寫的。
允許您的方法故意拋出是一個壞主意,並且絕對不符合FP的精神。 在具有失敗能力的方法的類型簽名中捕獲失敗可能更好。
private def listTail(ls: List[Int]): Try[List[Int]] = Try {
ls.tail
}
現在,您的用戶知道這將返回Success
或Failure
並且沒有魔術堆棧展開。 這已經使測試該方法更加容易。
您也可以使用此公式使用簡單的def safeTailList(ls: List[Int]) = listTail(l).getOrElse(Nil)
擺脫模式匹配-很好!
如果要對此進行測試,可以將其打包,然后進行相應的測試。
更好的主意是重新考慮您的算法。 有使內置安全尾巴成為可能的機器:
def safeTailList(ls: List[Int]) = ls.drop(1)
實際上,這是另一回事:通常,您不想測試私有方法,僅想測試公共方法,因為只要它們按承諾工作,它們便會定義您與外界的交互,他們會在乎什么?您的私有方法就可以了,這只是實現細節。
因此,最重要的是-只需測試您的safeListTail
,僅此而已,無需分別測試內部實現。
順便說一句,您不需要那里的match
: Try(listTail(ls)).getOrElse(handleEmptyList(ls))
等同於您在那里...實際上不是一個好主意,因為它吞沒了其他異常,而不僅僅是在列表為空時拋出的那個,一種更好的方法實際上是恢復match
但擺脫Try
:
ls match {
case Nil => handleEmptyList(ls)
case _ => listTail(ls)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.