I'm having trouble getting specs2 and scalacheck to cooperate. I have a simple class, Credit
, that takes a single integer within the range of 1 to 59 (anything outside of this range should throw an exception).
I want to define two tests: 1 test that validates the positive cases (any Credit(1)
... Credit(59)
validates successfully); and, any Credit
outside of that range should fail to validate (it should actually throw an exception when constructed). It seems like the right approach is to define an Arbitrary[Credit]
generator, like so:
implicit lazy val arbitraryCreditGenerator: Arbitrary[Credit] = Arbitrary(creditGenerator)
And then I would define an arbitraryBadCreditGenerator
too.
The problem is the implicit use of the arbitrary, and trying to figure out the syntax for using prop
with my two different arbitrary instances.
What I have so far is:
case class Credit(amount: Int)
object Credit {
implicit val creditValidator = validator[Credit] { c =>
c.amount should be > 0
c.amount should be < 60
}
}
class TestCreditModel extends Specification with ScalaCheck { def is = s2"""
Given a credit
When validation is performed
Then credits between 1 and 60 should be acceptable ${creditsAreValid}
And credits less than 1 or greater than 60 should not ${creditsAreInvalid}
"""
implicit lazy val arbitraryCreditGenerator: Arbitrary[Credit] = Arbitrary(creditGenerator)
val creditGenerator = Gen.choose(1,59).map(Credit(_))
val badCreditGenerator = (Gen.choose(-500, 500) suchThat (n => n < 1 || n > 59)).map(Credit(_))
def creditsAreValid = prop { (a: Credit) => validate(a).isSuccess must beTrue }
// Err... oops... how do I use my badCreditGenerator???
def creditsAreInvalid = prop { (a: badCreditGenerator) => validate(a).isSuccess must beFalse }
// ^ compile error... not defined
}
I'm using Accord for validation, so any attempt to create a Credit
with invalid range should fail.
This does not compile, because my use badCreditGenerator
is all wrong. I've been fiddling with it and trying to come up with the solution; ideally I'd have two arbitrary generators, one that generates "good" Credit
instances and one that tries to generate bad ones.
Maybe there's a better way?
Any help appreciated. Thank you!