Обратите внимание, что этот ответ для RC17 и значительно изменится в RC18. Вы правы, что, как и в других случаях создания сред, нам нужно реализовать функцию для построения нашей общей среды из имеющихся у нас модулей. Spe c имеет несколько встроенных комбинаторов, таких как provideManaged
, чтобы вам не пришлось делать это в самом тесте. Все они имеют «нормальные» варианты, которые будут предоставлять отдельную копию среды для каждого теста в наборе, и «общие» варианты, которые будут создавать одну копию среды для всего набора, когда это ресурс, который стоит дорого создавать. как служба Kafka.
Ниже приведен пример использования provideSomeManaged
для предоставления среды, расширяющей тестовую среду до теста.
В RC18 будет множество других предоставляет варианты, эквивалентные тем, что есть в ZIO, а также новую концепцию слоев, которая значительно упрощает создание составных сред для приложений ZIO.
import zio._
import zio.clock._
import zio.test._
import zio.test.environment._
import ExampleSpecUtil._
object ExampleSpec
extends DefaultRunnableSpec(
suite("ExampleSpec")(
testM("My Test") {
for {
time <- clock.nanoTime
_ <- Logging.logLine(
s"The TestClock says the current time is $time"
)
} yield assertCompletes
}
).provideSomeManaged(testClockWithLogging)
)
object ExampleSpecUtil {
trait Logging {
def logging: Logging.Service
}
object Logging {
trait Service {
def logLine(line: String): UIO[Unit]
}
object Live extends Logging {
val logging: Logging.Service =
new Logging.Service {
def logLine(line: String): UIO[Unit] =
UIO(println(line))
}
}
def logLine(line: String): URIO[Logging, Unit] =
URIO.accessM(_.logging.logLine(line))
}
val testClockWithLogging
: ZManaged[TestEnvironment, Nothing, TestClock with Logging] =
ZIO
.access[TestEnvironment] { testEnvironment =>
new TestClock with Logging {
val clock = testEnvironment.clock
val logging = Logging.Live.logging
val scheduler = testEnvironment.scheduler
}
}
.toManaged_
}