有,&;在ScalaCheck中的表达式中与:|短路
我正在尝试在Scala测试FlatSpec中创建一个基于属性的测试,该测试使用ScalaCheck有,&;在ScalaCheck中的表达式中与:|短路,scala,scalatest,boolean-expression,short-circuiting,scalacheck,Scala,Scalatest,Boolean Expression,Short Circuiting,Scalacheck,我正在尝试在Scala测试FlatSpec中创建一个基于属性的测试,该测试使用ScalaCheck:|运算符为结束布尔表达式的不同部分提供失败消息 但是,我遇到了一个问题,&&操作员没有短路。在这种情况下,表达式的前面部分将检查表达式的下一部分是否可以运行,否则后面的部分将引发异常 val value: Array[Int] = Array.fill(2)(0) val encoded = encode(value) val decoded: Option[Array[Int]] = decod
:|
运算符为结束布尔表达式的不同部分提供失败消息
但是,我遇到了一个问题,&&
操作员没有短路。在这种情况下,表达式的前面部分将检查表达式的下一部分是否可以运行,否则后面的部分将引发异常
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined :| "decoded None" &&
value.sameElements(decoded.get)
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined &&
value.sameElements(decoded.get)
下面是一个问题的例子。如果decoded
为None
,则表达式应在&&
上短路,以便decoded.get
不会运行,因为它会引发异常
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined :| "decoded None" &&
value.sameElements(decoded.get)
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined &&
value.sameElements(decoded.get)
当我在没有使用:|
操作符给出失败消息的情况下写入布尔值时,测试在decoded.isDefined
上失败,不会引发异常
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined :| "decoded None" &&
value.sameElements(decoded.get)
val value: Array[Int] = Array.fill(2)(0)
val encoded = encode(value)
val decoded: Option[Array[Int]] = decode(value)
decoded.isDefined &&
value.sameElements(decoded.get)
但是,当我使用:|
包含一条失败消息时,它会在value.sameElements(decoded.get)
行上使用NoSuchElementException
失败,并且不会显示decoded.isDefined
的失败消息,即使它的计算结果为false
我使用的导入和测试类声明如下:
import org.scalacheck.Prop._
import org.scalatest.prop.Checkers
import org.scalatest.{FlatSpec, Matchers}
class ByteRWTests extends FlatSpec with Matchers with Checkers {
我以以下方式填写财产支票:
it should "be equal" in {
check(
forAll { (int: Int) =>
int == int
}
)
}
有没有办法让&&
使用:|
的表达式短路,或者有没有解决此问题的方法?为什么您会看到差异
问题是,当布尔值的&
短路时,Prop
上的&
方法不短路,并且是否使用标签确定从布尔值到Prop
的隐式转换发生在何处。例如:
import org.scalacheck.Prop, Prop._
val value: Array[Int] = Array.fill(2)(0)
val decoded: Option[Array[Int]] = None
val p1: Prop = decoded.isDefined && value.sameElements(decoded.get)
val p2: Prop = decoded.isDefined :| "decoded None" && value.sameElements(decoded.get)
此处的p1
定义如下:
Prop.propBoolean(decoded.isDefined && value.sameElements(decoded.get))
而p2
为您提供以下信息:
(Prop.propBoolean(decoded.isDefined) :| "decoded None").&&(
Prop.propBoolean(value.sameElements(decoded.get))
)
(值得一提的是,这是另一个例子。)
变通办法
不幸的是,无法让Prop
上的&&
方法在此处执行您想要的操作,但您可以定义自己的连接版本,它可以执行以下操作:
def propAnd(p1: => Prop, p2: => Prop) = p1.flatMap { r =>
if (r.success) Prop.secure(p2) else Prop(_ => r)
}
然后:
scala> propAnd(decoded.isDefined :| "decoded None" , value.sameElements(decoded.get))
res1: org.scalacheck.Prop = Prop
scala> .check
! Falsified after 0 passed tests.
> Labels of failing property:
decoded None
这个方法实际上存在于ScalaCheck中,但它是。对实现的评论确实指出它“(应该在Prop模块中)”,因此如果您发现自己经常做这种事情,您可以尝试打开一个pull请求,将方法从命令移动到Prop
,并将其公开
不过,在这里给出的特定情况下,我可能会建议在选项上使用类似exists
的内容,而不是检查它是否已定义,然后使用get