簡體   English   中英

使用嘗試,成功,失敗的Scala中的單元測試策略

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

現在,您的用戶知道這將返回SuccessFailure並且沒有魔術堆棧展開。 這已經使測試該方法更加容易。

您也可以使用此公式使用簡單的def safeTailList(ls: List[Int]) = listTail(l).getOrElse(Nil)擺脫模式匹配-很好!

如果要對此進行測試,可以將其打包,然后進行相應的測試。

更好的主意是重新考慮您的算法。 有使內置安全尾巴成為可能的機器:

def safeTailList(ls: List[Int]) = ls.drop(1)

實際上,這是另一回事:通常,您不想測試私有方法,僅想測試公共方法,因為只要它們按承諾工作,它們便會定義您與外界的交互,他們會在乎什么?您的私有方法就可以了,這只是實現細節。

因此,最重要的是-只需測試您的safeListTail ,僅此而已,無需分別測試內部實現。

順便說一句,您不需要那里的matchTry(listTail(ls)).getOrElse(handleEmptyList(ls))等同於您在那里...實際上不是一個好主意,因為它吞沒了其他異常,而不僅僅是在列表為空時拋出的那個,一種更好的方法實際上是恢復match但擺脫Try

  ls match {
     case Nil => handleEmptyList(ls)
     case _ => listTail(ls)
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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