I am trying to use ScalaCheck's forAll
in conjunction with behavior functions but I'm running into issues. The behavior functions look like this:
def someBehaviour(args: FunArgs)
where FunArgs
is basically a union type of the various possibilities that I want to verify. So, there is a FunArgs1
and a FunArgs2
that both inherit from FunArgs
but have different members (e.g. one has two Int
s whereas the other has a String
, a Long
and an Int
). The actual function I want to test deals with these different cases internally.
sealed trait FunArgs
final case class FunArgs1(a: Int, b: Int) extends FunArgs
final case class FunArgs2(x: Long, y: Int, z: String) extends FunArgs
sealed trait FunRes
final case class FunRes1(...) extends FunRes
final case class FunRes2(...) extends FunRes
def someFun(args: FunArgs): FunRes = args match {
// do stuff and return some subclass of FunRes
}
trait SomeBehaviors { this: UnitSpec =>
def someBehavior(args: FunArgs) {
it should "do stuff " in {
val result = someFun(args) // creates an instance of FunRes
...
result should contain theSameElementsAs expected
}
it should "do more stuff" in {
// similar to before
...
result should contain theSameElementsAs expected
}
}
}
Inside the behavior function are multiple in
clauses because all functions need to satisfy the same behavior.
The problem is that I cannot do this because it will create duplicate test names:
forAll { (a: Int, b: Int) =>
someBehavior(FunArgs1(a, b))
}
But I also cannot do this because of 'should' inside 'in':
"someFun1" should "do stuff" in {
forAll { (a: Int, b: Int) =>
someBehaviour(FunArgs1(a, b))
}
}
And the line below doesn't give me the possibility of using generators because I would have to put the forAll
inside the behavior where I do not necessarily know how many and what types the arguments are.
"someFun1" should behave like someBehaviour(MakeFunArgs1(a, b))
Is there a way to do what I want to?