【问题标题】:No implicit view available from AnyVal => org.scalacheck.Prop. [error] propertyAnyVal => org.scalacheck.P​​rop 没有可用的隐式视图。 [错误] 属性
【发布时间】:2016-03-09 08:13:38
【问题描述】:

我有 2 个问题

我正在努力学习scalacheck

问题 1)

这是我正在编写的抛出错误的测试。您能否指出我应该阅读文档中的哪个页面以了解此错误背后的原因。

case class Student(name:String, age:Int, mathsScore:Int, scienceScore:Int){
  require(name != null ,"Name cannot be blank")
  require(age > 3 ,"Age should be more than 3")
  require(mathsScore >= 0 , "Score should not be negative")
  require(scienceScore >= 0 ,"Score should not be negative")

  val totalScore = mathsScore + scienceScore
}

测试是

object CaseStudySpecification extends Properties("Case Study Specification") {

  property("nullName") = forAll { (name: String, age: Int, ms: Int, ss: Int) =>
    if (name == null)
      Prop.throws(classOf[IllegalArgumentException]) {
        val x = Student(name, age, ms, ss)
      }
  }
}

错误是

 No implicit view available from AnyVal => org.scalacheck.Prop.
[error]   property("nullName") = forAll { (name: String, age: Int, ms: Int, ss: Int) =>
[error]                                 ^

问题 2)

官方文档给出了一个示例测试类

  property("stringLength") = Prop.forAll { s: String =>
    val len = s.length
    (s+s).length == len+len
  }

我还读到它可以写成

  val stringLength = Prop.forAll { s: String =>
    val len = s.length
    (s+s).length == len+len
  }

我如何运行第二种形式的测试代码,因为当我运行 sbt test 时,第二个版本没有任何反应。

以上两个sn-ps都在

object Ch3 extends Properties("String") {

}

【问题讨论】:

标签: scalacheck


【解决方案1】:

Prop.forAll 的签名被调用需要一个返回 Prop 的函数(或者至少可以隐式转换为 Prop 的东西),但是,正如所写的那样,该函数:

(name: String, age: Int, ms: Int, ss: Int) => {
  if (name != null) Prop.throws(...)
}

具有 (String, Int, Int, Int) => AnyVal 的推断签名,并且不存在到属性的隐式转换。因此编译错误。该函数可以通过确保它始终返回一个布尔值来轻松修复,如下所示:

property("nullName") = forAll { (name: String, age: Int, ms: Int, ss: Int) =>
  if (name == null) Prop.throws(classOf[IllegalArgumentException]) {
    Student(name, age, ms, ss)
  } 
  else true
}

这将导致应用implicit Boolean => Prop 函数,并且代码编译。更惯用的解决方法是使用蕴含运算符重写属性:

property("nullName") = forAll { (name: String, age: Int, ms: Int, ss: Int) =>
  name == null ==>
    Prop.throws(classOf[IllegalArgumentException]) {
      Student(name, age, ms, ss)
    }
}

但是,拒绝太多生成的输入并不是一个好主意,而且由于 scalacheck 生成的第一个值实际上是 null,因此该属性最终为“未确定”,因此测试仍然失败。您可以将您的属性简化为:

property("nullName") = forAll { (age: Int, ms: Int, ss: Int) =>
  Prop.throws(classOf[IllegalArgumentException]) {
    Student(null, age, ms, ss)
  }
}

由于这不是一个 scalacheck 特有的问题,而是一个通用的 Scala 问题,所以 scalacheck 文档中没有专门介绍它;您可以阅读implicit views 了解更多背景信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2020-10-06
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多