0

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") {

}
user2230605
  • 2,199
  • 4
  • 25
  • 37
  • I split off the second half of the original into a separate StackOverflow question: http://stackoverflow.com/questions/38284055/why-does-a-scalacheck-prop-value-not-get-evaluated – Pavel Jul 09 '16 at 16:47

1 Answers1

3

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.

Pavel
  • 3,303
  • 24
  • 31