zio-logging 在测试计划任务时的行为与 ZIO 中的 prod 不同

问题描述

我一直在测试可重复的任务。 在测试之外运行时可以正常工作,但在测试中失败。看起来 zio-logging 在测试时表现得有些不同(好像它是“阻塞”)。当我用普通的 Console 调用替换日志记录时,它可以工作,当我分叉日志记录调用时也是如此。

谁能告诉我我做错了什么或者为什么会这样?

package scheduler

import zio.clock.Clock
import zio.duration.durationInt
import zio.logging.Logging
import zio.test.Assertion.equalTo
import zio.test.environment.TestEnvironment
import zio.test.{DefaultRunnableSpec,ZSpec}
import zio.{Has,Ref,ZIO}

/*
Testing ZIO-based repeated tasks. It works fine locally,but when there is logging within the task it stops working under test.
It looks like it somehow holds execution after first iteration,because adding `fork` to logging statement within `doWorkLogging` makes test pass
*/

object SimpleSpec extends DefaultRunnableSpec {

  private val doWorkLogging = for {
    _   <- ZIO.accessM[Has[Ref[Long]]](_.get.update(_ + 1))
    Now <- zio.clock.instant
    _   <- zio.logging.log.info(s"Run $Now")
  } yield ()

  private val doWorkConsole = for {
    _   <- ZIO.accessM[Has[Ref[Long]]](_.get.update(_ + 1))
    Now <- zio.clock.instant
    _   <- zio.console.putStrLn(s"Run $Now")
  } yield ()

  private val logging = Logging.console()

  override def spec: ZSpec[Environment,Any] = suite("simple test")(
    testM("logging + delay work with Clock.live") {
      val counter = Ref.make(0L).toLayer
      val looper  = doWorkLogging *> (zio.UIO.unit.delay(2.seconds) *> doWorkLogging).forever
      (for {
        f     <- looper.fork
        _     <- zio.clock.sleep(5.seconds)
        ref   <- ZIO.service[Ref[Long]]
        count <- ref.get
        _     <- f.interrupt
      } yield zio.test.assert(count)(equalTo(3L))).provideSomeLayer(Clock.live ++ logging ++ counter)
    },// Why is this one failing with count = 1?
    testM("logging + delay don't work with TestEnvironment") {
      val counter = Ref.make(0L).toLayer
      val looper  = doWorkLogging *> (zio.UIO.unit.delay(2.seconds) *> doWorkLogging).forever
      (for {
        f     <- looper.fork
        _     <- zio.test.environment.TestClock.adjust(5.seconds)
        ref   <- ZIO.service[Ref[Long]]
        count <- ref.get
        _     <- f.interrupt
      } yield zio.test.assert(count)(equalTo(3L))).provideSomeLayer[TestEnvironment](logging ++ counter)
    },// And why this one (with logging replaced with console) works then?
    testM("console + delay work with TestEnvironment") {
      val counter = Ref.make(0L).toLayer
      val looper  = doWorkConsole *> (zio.UIO.unit.delay(2.seconds) *> doWorkConsole).forever
      (for {
        f     <- looper.fork
        _     <- zio.test.environment.TestClock.adjust(5.seconds)
        ref   <- ZIO.service[Ref[Long]]
        count <- ref.get
        _     <- f.interrupt
      } yield zio.test.assert(count)(equalTo(3L))).provideSomeLayer[TestEnvironment](logging ++ counter)
    },)
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)