首页 > 解决方案 > 基于 Scala 中的模式生成随机/样本 json

问题描述

我需要生成一些随机的 json 样本,动态地符合模式。这意味着输入将是一个模式(例如 json-schema),而输出将是一个符合它的 json。

我正在寻找指针。有什么建议么 ?

标签: scalacircescalacheck

解决方案


这不是完整的解决方案,但您可以从这里获得。

假设我们有我们想要生成的域对象:

case class Dummy1(foo: String)
case class Dummy11(foo: Dummy1)

如果我们这样做:


object O {
  implicit def stringR: Random[String] = new Random[String] {
    override def generate(): String = "s"
  }

  implicit def intR: Random[Int] = new Random[Int] {
    override def generate(): Int = 1
  }

  implicit def tupleR[T1: Random, T2: Random]: Random[(T1, T2)] = new Random[(T1, T2)] {
    override def generate(): (T1, T2) = {
      val t1: T1 = G.random[T1]()
      val t2: T2 = G.random[T2]()
      (t1, t2)
    }
  }
}

object G {
  def random[R: Random](): R = {
    implicitly[Random[R]].generate()
  }
}

然后我们将能够生成一些原始值:

  import O._

  val s: String = G.random[String]()
  val i: Int = G.random[Int]()
  val t: (Int, String) = G.random[(Int, String)]()

  println("s=" + s)
  println("i=" + i)
  println("t=" + t)

现在要跳转到自定义类型,我们需要添加

  def randomX[R: Random, T](f: R=>T): Random[T] = {
    val value: Random[R] = implicitly[Random[R]]
    new Random[T] {
      override def generate(): T = f.apply(value.generate())
    }
  }

到我们的G对象。

现在我们可以

  import O._
  val d1: Dummy1 = G.randomX(Dummy1.apply).generate()
  println("d1=" + d1)

甚至付出一些额外的努力

  import O._
  implicit val d1Gen: Random[Dummy1] = G.randomX(Dummy1.apply)
  val d11: Dummy11 = G.randomX(Dummy11.apply).generate()
  println("d11=" + d11)

现在您需要将它扩展到您拥有的所有原语,添加具有超过 1 个字段的随机和支持类的实际实现,然后您就可以开始了。

你甚至可以用它制作一些花哨的库。


推荐阅读