Search code examples
scalascalatestscalacheck

How to get defined Arbitrary?


I am using ScalaTest and ScalaCheck. I wrote a custom generator and arbitrary generator as following:

import java.time.LocalDateTime

import org.scalacheck._
import org.scalatest.PropSpec
import org.scalatest.prop.Checkers
import Gen._
import Arbitrary.arbitrary


class AuthJwtSpec extends PropSpec with Checkers {

  private val start = LocalDateTime.now.atZone(java.time.ZoneId.systemDefault()).toEpochSecond
  private val end = LocalDateTime.now.plusDays(2).atZone(java.time.ZoneId.systemDefault()).toEpochSecond
  private val pickTime = Gen.choose(start, end)

  private val authUser: Arbitrary[AuthUser] =
    Arbitrary {
      for {
        u <- arbitrary[String]
        p <- arbitrary[String]
      } yield AuthUser(u, p)
    }

  property("Generate JWT token.") {
    check(Prop.forAll(authUser, pickTime) {(r1: AuthUser, r2: Long) =>

      ???
    })
  }
}

The problem is, that r1 has type Arbitrary[AuthUser] but I need AuthUser, how to get it?


Solution

  • As I see, the problem is with authUser field - it should be Gen[AuthUser], not Arbitary[AuthUser]:

    import java.time.LocalDateTime
    
    import org.scalacheck._
    import org.scalatest._
    import prop._
    
    case class AuthUser(u: String, p: String)
    
    class AuthJwtSpec extends PropSpec with Checkers with PropertyChecks  {
      private val start = LocalDateTime.now.atZone(java.time.ZoneId.systemDefault()).toEpochSecond
      private val end = LocalDateTime.now.plusDays(2).atZone(java.time.ZoneId.systemDefault()).toEpochSecond
    
      private val pickTime: Gen[Long] = Gen.choose(start, end)
    
      // AuthUser should be Gen[AuthUser], not Arbitary[AuthUser]
      private val authUser: Gen[AuthUser] =
          for {
            u <- Arbitrary.arbitrary[String]
            p <- Arbitrary.arbitrary[String]
          } yield AuthUser(u, p)
    
      property("Generate JWT token.") {
        val prop = Prop.forAll(authUser, pickTime) {(user: AuthUser, time: Long) =>
          println(s"User: $user")
          println(s"Time: $time")
          // Property checks must always return true or false
          true
        }
        check(prop)
      }
    }