scala 用于共享环境的ZIO TestClock

omjgkv6w  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(79)

看起来操作ZIO TestClock对于作为共享层提供的服务不起作用。下面是一个示例来演示它:

case class TimerService(in: Queue[Int], out: Queue[Instant]) {
    def serve = ZStream.fromQueue(in)
      .takeWhile(_ > 0)
      .foreach { _ => Clock.instant.flatMap(out.offer _) }

    def ask(n: Int) = in.offer(n) *> out.take.map(_.toEpochMilli / 1000)
  }

  object TimerService {
    def fork = for {
      in <- Queue.bounded[Int](1)
      out <- Queue.bounded[Long](1)
      ts = TimerService(in, out)
      _ <- ts.serve.fork
    } yield ts
  }

  ...
  def spec: {
    suite("Shared Timer Service") ( 
     test("this does not work!") {
      for {
          ts <- ZIO.service[TimerService]
          answer <- TestClock.adjust(1.second) *> ts.ask(1)
      } yield assertTrue(answer == 1)
     }
    ).provideSomeLayerShared(ZLayer.fromZIO(TimerService.fork))
     .provideSomeLayer(ZLayer.fromZIO(TestClock.setTime(Instant.ofEpochMilli(0)))) +
    
   suit("Own timer service") (
    test("this does!") {
       for { 
         ts <- ZIO.service[TimerService]
         answer <- TestClock.adjust(1.second) *> ts.ask(1)
      } yield assertTrue(answer == 1)
    }
   ).provideSomeLayer(ZLayer.fromZIO(TimerService.fork))
    .provideSomeLayer(ZLayer.fromZIO(TestClock.setTime(Instant.ofEpochMilli(0))))
 }

字符串
因此,服务基本上监听一个队列上的请求,并在另一个队列上用它认为是当前时间戳的时间来响应。测试分叉服务,将时钟提前一秒,然后询问服务现在是什么时间。
第一次测试失败(响应是0而不是1 -即使初始时间被正确设置,时钟也不会提前),第二个成功。唯一的区别是,在第一种情况下,分叉的服务层是Shared,而在第二种情况下不是。想法是分叉一个服务示例一次,并将其用于所有测试,而不是每次都产生一个单独的。这不可能吗?

0kjbasz6

0kjbasz61#

您可以使用TestAspect.before在特定测试用例中对环境进行更改(这不会影响其他测试用例)。
例如

... @@ TestAspect.before(TestClock.adjust(1.second))

字符串
有一篇旧文章,对这个主题有更多的了解,我推荐阅读它-https://hmemcpy.com/2021/11/working-with-shared-dependencies-in-zio-test/
从本质上讲,共享层只构造一次,并复制到所有测试中(如果构造成本很高,则可以获得性能),但不能在测试中修改它。
修改它的唯一可能的方法是通过TestAspects。

相关问题