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