ZIO-Test如何使用定时时间?

How to use regular time in ZIO-Test?

在处理 zio-spark 时,我们无法在未使用 zio.Clock 的测试中竞争效果。效果不会被打断。有办法解决这个问题吗?

package zio.spark.effect

import zio._
import zio.test.TestAspect.timeout
import zio.test._


object WeirdClocks extends DefaultRunnableSpec {
  def wait(seconds: Int): UIO[Int] = UIO(Thread.sleep(seconds * 1000)).as(seconds)

  override def spec: ZSpec[TestEnvironment, Any] = suite("clock")(
    test("raceTest") {
      wait(5).race(wait(15)) map (n => assertTrue(n == 5))
    } @@ timeout(10.seconds)
  )
}

这是预期的行为,与 ZIO 测试或 Clock.

没有任何关系

ZIO中的中断不会return直到效果被成功中断,这是资源安全的重要保障。在 wait(5).race(wait(15)) 中,wait(5) 在 5 秒后赢得比赛。那时 race 试图打断 wait(15)。但是,中断通常发生在“效果之间”,并且 wait(15) 是一个单独的副作用代码块,因此通常无法安全地中断它。结果,中断挂起,直到wait(15)执行完毕,但此时已经过去了15秒,测试已经超时。

如果您不想等待中断完成,您可以使用 disconnect 运算符,例如 wait(5).race(wait(15).disconnect)。通过此更改,您的测试将按书面方式通过。您还可以使用 attemptBlockingInterrupt 指示 ZIO 运行时尝试通过中断底层线程来中断像这样的单个副作用代码块,尽管这是相对重量级的。