Scalacheck结合Inside trait使用时编译错误排查求助
解决Scalatest PropSpec中Assertion到Prop的隐式转换错误
你遇到的问题核心在于Scalacheck的forAll期望闭包返回Prop类型,但Scalatest的断言(包括inside块)返回的是Assertion类型,两者之间缺少自动转换的隐式视图,所以编译报错。
为什么会这样?
你提到以为inside块返回布尔值,但实际上Scalatest的匹配器(比如shouldEqual、inside)返回的是Assertion——这是一个标记类型,底层通过抛出TestFailedException来表示断言失败,并非返回布尔值。而Scalacheck的属性检查系统要求每个测试用例返回Prop(属性),用来表示测试的成功/失败状态,所以直接把断言放在forAll的闭包里会类型不匹配。
解决方案
最简单的办法是给测试类混入ScalaCheckPropertyChecks trait,它提供了Assertion => Prop的隐式转换,能自动把Scalatest的断言转换成Scalacheck需要的Prop类型。
修改后的测试代码如下:
import org.scalatest.PropSpec import org.scalatest.matchers.should.Matchers import org.scalatest.Inside import org.scalatestplus.scalacheck.Checkers import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks import org.scalacheck.Gen class ExercisesPropSpec extends PropSpec with Checkers with Matchers with Inside with ScalaCheckPropertyChecks { import Exercises._ lazy val genPairs = for { left <- Gen.listOfN(10, Gen.alphaChar) right <- Gen.listOfN(10, Gen.alphaChar) } yield (left.mkString, right.mkString) property("pattern match tuples of alphanumerics to our custom pair class") { check(forAll(genPairs) { case (left: String, right: String) => val pair = Pair(left, right) inside(pair) { case Pair(firstName, lastName) => firstName shouldEqual left lastName shouldEqual right } }) } }
另一种手动转换方式(如果不想混入额外trait)
如果你不想引入ScalaCheckPropertyChecks,可以手动用org.scalacheck.Prop.fromAssertion把断言包裹成Prop:
import org.scalacheck.Prop.fromAssertion // ... 在forAll闭包中: fromAssertion { inside(pair) { case Pair(firstName, lastName) => firstName shouldEqual left lastName shouldEqual right } }
这样也能让闭包返回Prop类型,解决编译错误。
内容的提问来源于stack exchange,提问作者vasigorc
相关产品推荐
相关产品推荐

