scala - 如何覆盖 ScalaCheck 的一些生成器以强制(自动)生成精炼类型?仅非空列表,例如

标签 scala scalacheck property-based-testing

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

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)

但是没有成功。

最佳答案

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

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

这是一个示例,其中 Arbitrary 长列表默认情况下是非空的,但对于 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
  }
}

关于scala - 如何覆盖 ScalaCheck 的一些生成器以强制(自动)生成精炼类型?仅非空列表,例如,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55398947/

相关文章:

scala - Akka Actor 无法连接到 Scala Actor 可以连接的远程服务器

haskell - 使用 Hedgehog(或任何其他基于属性的测试框架)生成随机 GADT 的最安全方法

c# - 在 FsCheck 中将两个生成器组合成一个任意生成器

Scala:我可以声明一个在编译时不会生成 getter 和 setter 的公共(public)字段吗?

scala - 惰性字段的序列化如何工作?

scalaz - 使用 specs2 和 scalaz-scalacheck-binding 来测试法律

scalac 在 ScalaTest 测试中发现错误的 forAll 方法

haskell - 在 Hedgehog 中通过 'Gen' 或通过 'forAll' 生成随机输入的区别

scala - 具有守护程序风格语义的actor

scalacheck - 当第二个参数的生成依赖于第一个参数时,如何编写带有两个参数的测试?