Anders Martini
Anders Martini

Reputation: 948

How can I provide a custom header to a ZIO during tests

I have service that returns a ZIO[Has[MyCustomHeader]], and I'm having trouble testing it.

Other services in our organisation are tested by converting ZIO to Twitterfuture using runtime.unsafeRunToFuture (where runtime is a Runtime[ZEnv] ) and then awaiting the future, thus running the tests in blocking mode.

However this service has a Has[] requirement and runtime.unsafeRunToFuture doesnt handle those. So far my approach has been to try to convert my ZIO[Has[MyCustomHeader]] to a ZIO[ZEnv], but I've yet to succeed at this.

from what I gather I need to provide a ZLayer via ZIO.provideSomeLayer() but I'm simply too stupid to understand how to construct a ZLayer properly?

Am I even on the right path here? and if so, How do I construct a ZLayer with a static value for MyCustomHeader to use in my tests?

This is how far along I am at trying to add a header for testing purposes: it doesn't work, but might illustrate what I'm trying to achieve..maybe... I'm pretty confused myself:

object effectAwait {
  implicit class ZioEffect[A](private val value: ZIO[Has[EnvironmentHeader], RequestFailure, A]) extends AnyVal {
    final def await(implicit runtime: Runtime[ZEnv] = Runtime.default): A = {
      val zmanaged = ZManaged.fromEffect(value).provide(Has(EnvironmentHeader("test")))
      val layered =  value.provideSomeLayer(zmanaged.toLayer)
      val sf = runtime.unsafeRunToFuture(layered)

      Await.result(sf, 10.seconds)
    }
  }
}

this however gives me the error:

could not find implicit value for izumi.reflect.Tag[A]. Did you 
forget to put on a Tag, TagK or TagKK context bound on one of the 
parameters in A? e.g. def x[T: Tag, F[_]: TagK] = ...


<trace>: 
 deriving Tag for A, dealiased: A:
 could not find implicit value for Tag[A]: A is a type parameter without an implicit Tag!
     val layered =  value.provideSomeLayer(zmanaged.toLayer)

Upvotes: 1

Views: 324

Answers (1)

user1274426
user1274426

Reputation:

I think you can just use ZIO.provideLayer (instead of provideSomeLayer) here :)

Also, there's a runtime.unsafeRun that will wait for the result as well, so you don't necessarily have to convert it to a Future. Also, also, instead of relying on an implicit runtime, there's always zio.Runtime.default that you can use anywhere (it's a Runtime[ZEnv] so it should work just as well, unless you've otherwise customized the runtime's behavior)

Upvotes: 1

Related Questions