Search code examples
scalascalacheck

Use ScalaCheck generator inside another generator


I have a generator that creates a very compelx object. I cannot create this object through something like

val myGen = for{
 a <- Gen.choose(-10,10)
 ...
} yield new MyClass(a,b,c,...)

I tried an approach of creating a custom generator like this

val myComplexGen :Gen[ComplexObject] = {

  ...
  val myTempVariable = Gen.choose(-10,10)
  val otherTempVal = Gen.choose(100,2000)

  new MyComplexObject(myTempVariable,otherTempVal,...)
}

and then

test("myTest") {
  forAll(myComplexGen){ complexObj => 
        ... // Here, complexObj.myTempVariable is always the same through all the iterations
 }
}

While this works, the values generated are always the same. The inner Gen.choose yield always the same value.

Is there any way I can write a custom Gen with its own logic, and use inner Gen.choose inside, that would be random ?


Solution

  • I've been able to workaround the problem. The solution is definitely not elegant but that's the only way I could work it out.

    I have transformed myComplexGen into a def, and called it inside another gen with dummy variables

    def myComplexGen :ComplexObject = {
    
      ...
      val myTempVariable = Gen.choose(-10,10)
      val otherTempVal = Gen.choose(100,2000)
    
      new MyComplexObject(myTempVariable,otherTempVal,...)
    }
    

    val realComplexGen :Gen[ComplexObject] = for {
        i <- Gen.choose(0,10) // Not actually used, but for cannot be empty
    } yield myComplexGen()
    

    Now I can use realComplexGenin a forAll and the object is really random.