No implicit view available from AnyVal => org.scalacheck.Prop. [error] property

久未见 提交于 2019-12-12 10:21:58

问题


I have 2 questions

I am trying to learn scalacheck

Question 1)

Here is the test I am writing which is throwing the error. Can you please point to which page from docmentation i should read to understand reason behind this error.

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
}

Test is

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)
      }
  }
}

Error is

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

Question 2)

The official documentation gives one example test class as

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

I also read that it can be written as

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

How can i run the second form of test code , as when i run sbt test nothing happens for second version.

Both of the above snippets are in

object Ch3 extends Properties("String") {

}

回答1:


The signature of Prop.forAll being called requires a function returning Prop (or at least something that can be implicitly converted to Prop) but, as written, the function:

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

has an inferred signature of (String, Int, Int, Int) => AnyVal, and there does not exist an implicit conversion into a property. Hence the compilation error. The function could be trivially fixed by making sure it always returns a Boolean as follows:

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
}

This results in the implicit Boolean => Prop function being applied, and the code compiles. A more idiomatic fix would be to rewrite the property using the implication operator:

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

However it is not a good idea to reject too much of the generated input and since the very first value that scalacheck generates is in fact null, the property ends up as 'undecided' so the test still fails. You could just simplify your property to:

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

As this isn't a scalacheck-specific problem but rather a general Scala one it isn't specifically covered in the scalacheck documentation; you can read up on implicit views for more background.



来源:https://stackoverflow.com/questions/35886206/no-implicit-view-available-from-anyval-org-scalacheck-prop-error-property

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!