将 scalacheck Gen 与 Future In Scala 相结合



基本上我正在尝试制作作为HTTP请求结果的生成器,因此我经常以Gen[EitherT[Future, Error, T]]这样的类型结束。

问题是似乎没有任何一元实例(所以我可以做sequence,或单元变压器(让我组合不同的Gen[EitherT[Future, Error, T]]实例

例如,假设我们有以下函数

def genUser: Gen[EitherT[Future, Error, User]]

def genAccounts(user: User): Gen[EitherT[Future, Error, List[Account]]

这个想法是能够正确地组合Gen[EitherT[Future, Error,T]类型,以便genAccounts调用genUser,即类似

def genAccounts(user: User): Gen[EitherT[Future, Error, List[Account]] = for { user <- genUser accounts <- genAccounts(user) } yield accounts

scalacheckGen也提供了一种将Future提升到Gen的方法(即一种从Gen[Future[T]]到仅Gen[T]的方法(。即使这是阻塞,如果在我们生成最终Gen属性时只发生一次,那也不是一个大问题

截至目前(2022 年底(,ScalaCheck 方面似乎没有对有效生成器的本机支持。有一个关于异步Prop的问题。如问题中所述,该解决方案现在在库scalacheck效果中实现。

上述功能可能是一种解决方法,但需要嵌套异步属性而不是直接生成数据,例如

import org.scalacheck.Gen
import org.scalacheck.effect.PropF
import java.util.UUID
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, Future }
object TestAsync {
case class Box(uuid: UUID)
case class Wrapped(box: Box, name: Option[String])
val propF: PropF[Future] = PropF.forAllF(Gen.uuid) { uuid =>
Future(Box(uuid)).map { box =>
PropF.forAllF(Gen.alphaNumStr) { name =>
Future(Wrapped(box, Some(name))).map { wrapped =>
PropF.boolean[Future](wrapped.name.nonEmpty)
}
}
}
}
def main(args: Array[String]): Unit = {
Await.result(
propF
.check()
.map(println),
Duration.Inf
)
}
}

该用例仅用于演示,并且已经表明使用嵌套PropF有些涉及。

另一种选择可能是使用ZIO,它处理的值与EitherT[Future, Error, A]非常相似,并且具有有效的属性。

相关内容

  • 没有找到相关文章

最新更新