3

我有一个相当大的案例类结构,并且在这个结构的深处,我有我想要改进的字段,例如,使列表非空。是否可以使用scalacheck-magnolia项目的自动派生来告诉 ScalaCheck 使这些列表非空(不具体提供每个字段)?例子:

import com.mrdziuban.ScalacheckMagnolia.deriveArbitrary
import org.scalacheck.Arbitrary
import org.scalacheck.Gen

case class A(b: B, c: C)
case class B(list: List[Long])
case class C(list: List[Long])

// I've tried:
def genNEL[T: Gen]: Gen[List[T]] = Gen.nonEmptyListOf(implicitly[Gen[T]])
implicit val deriveNEL = Arbitrary(genNEL)

implicit val deriveA = implicitly[Arbitrary[A]](deriveArbitrary)

但它没有成功。

4

1 回答 1

1

我不确定如何通用,因为我不熟悉Arbitrary使用 scalacheck-magnolia 进行自动推导。似乎 scalacheck-magnolia 适合派生Arbitraryfor case 类,但可能不适用于容器(列表、向量、数组等)。

如果你只想使用普通的 ScalaCheck,你可以自己定义隐ArbitraryA。手工操作是一些额外的样板,但如果您想为数据结构的不同部分使用不同的生成器,它的好处是您可以拥有更多的控制权。

这是一个示例,其中Arbitrarylong 列表默认为非空,但对于B.

implicit val listOfLong =
  Arbitrary(Gen.nonEmptyListOf(Arbitrary.arbitrary[Long]))


implicit val arbC = Arbitrary {
  Gen.resultOf(C)
}

implicit val arbB = Arbitrary {
  implicit val listOfLong =
    Arbitrary(Gen.listOf(Arbitrary.arbitrary[Long]))
  Gen.resultOf(B)
}

implicit val arbA = Arbitrary {
  Gen.resultOf(A)
}

property("arbitrary[A]") = {
  Prop.forAll { a: A =>
    a.b.list.size >= 0 && a.c.list.size > 0
  }
}
于 2019-03-28T15:50:53.720 回答