scalaziozio-test

Why is it not possible to extract the Layers in a variable in ZIO Test


When providing the Layers for my tests I stumbled over this strange behaviour, that it is not possible to extract the layers in a value.

This code compiles:

  def spec: ZSpec[environment.TestEnvironment, Any] =
    suite("EnvironmentLoaderSuites")(
        testM("the Config is correct") {
          assertM(environmentLoader.bpfEnv())(
            equalTo(expectedEnv))
        }
    ).provideCustomLayer(Console.live >>> loggings.consoleLogger >>> environmentLoader.live(testEnvPath))

When I now extract the layers like this:

  val layers = Console.live >>> loggings.consoleLogger >>> environmentLoader.live(testEnvPath)
  def spec: ZSpec[environment.TestEnvironment, Any] =
    suite("EnvironmentLoaderSuites")(
        testM("the Config is correct") {
          assertM(environmentLoader.bpfEnv())(
            equalTo(expectedEnv))
        }
    ).provideCustomLayer(layers)

I get the following compile exception:

Error:(48, 26) type mismatch;
 found   : zio.ZLayer[Any,Throwable,finnova.bpf.client.environmentLoader.EnvironmentLoader]
    (which expands to)  zio.ZLayer[Any,Throwable,zio.Has[finnova.bpf.client.environmentLoader.Service]]
 required: zio.ZLayer[zio.test.environment.TestEnvironment,zio.test.TestFailure[Any],?]
    (which expands to)  zio.ZLayer[zio.Has[zio.clock.Clock.Service] with zio.Has[zio.console.Console.Service] with zio.Has[zio.system.System.Service] with zio.Has[zio.random.Random.Service] with zio.Has[zio.blocking.Blocking.Service] with zio.Has[zio.test.Annotations.Service] with zio.Has[zio.test.environment.TestClock.Service] with zio.Has[zio.test.environment.TestConsole.Service] with zio.Has[zio.test.environment.Live.Service] with zio.Has[zio.test.environment.TestRandom.Service] with zio.Has[zio.test.Sized.Service] with zio.Has[zio.test.environment.TestSystem.Service],zio.test.TestFailure[Any],?]
    ).provideCustomLayer(layers)

Is this a restriction of ZIO Test or do I miss something?


Solution

  • I believe you need to lift the failure type of your layer to a TestFailure. You can do this with layer.mapError(TestFailure.fail). When you provided it directly the compiler may have widened the type since it was not fully known yet whereas now since you have defined an intermediate val the type is fully determined.