softwaremill / sttp

The Scala HTTP client you always wanted!
https://sttp.softwaremill.com
Apache License 2.0
1.46k stars 309 forks source link

A problem with a stub & AsyncHttpClientZioBackend #726

Closed gchudnov closed 4 years ago

gchudnov commented 4 years ago

Hi

I'm trying to write a test for zio "1.0.3" & sttp "3.0.0-RC5" and have an issue with Has[_].

java.lang.Error: Defect in zio.Has: Set(SttpBackend[=λ %2:0 → ZIO[-Any,+Throwable,+2:0],+{ZioStreams & package::WebSockets}]) statically known to be contained within the environment are missing

it looks like a problem in ZIO and I raised an issue https://github.com/zio/zio/issues/4340 there

but I noticed there is a comment in sttp regarding Has and wondering if there is a workaround for the problem I bumped into? or if I'm writing this test in a wrong way ?

the minimized code that gives an error looks something like:

import sttp.client3._
import sttp.client3.asynchttpclient.zio.stubbing._
import sttp.client3.asynchttpclient.zio.{ send, AsyncHttpClientZioBackend, SttpClient, SttpClientStubbing }
import sttp.model.Uri
import zio.test.Assertion._
import zio.test._
import zio.{ Layer, ZIO }

object SendSpec extends DefaultRunnableSpec {

  private val eventsUri = Uri("https://some-url.org/")
  private val request   = basicRequest.get(eventsUri)

  override def spec: ZSpec[Environment, Failure] =
    suite("SendSpec")(
      testM("can be tested with an sttp stub") {
        val httpEnv: Layer[Throwable, SttpClient with SttpClientStubbing] = AsyncHttpClientZioBackend.stubLayer

        val runEffect: ZIO[SttpClient, Throwable, TestResult] = for {
          res <- send(request)
        } yield assert(res.body)(isRight)

        val stubEffect: ZIO[SttpClientStubbing, Throwable, Unit] = for {
          _ <- whenAnyRequest.thenRespond("RESPONSE")
        } yield ()

        val program: ZIO[SttpClient with SttpClientStubbing, Throwable, TestResult] = stubEffect *> runEffect

        program.provideCustomLayer(httpEnv)
      }
    )
}

An advice is appreciated.

Thank you, Grigorii

adamw commented 4 years ago

I've just tested locally and the test worked fine (well I was using scalatest instead of zio-test, could this be a factor)? Maybe you could give more details on the exception, where is it thrown exactly?

gchudnov commented 4 years ago

hm. got it, thank you for reply. let me check without zio-test...

I'm constantly getting an error inside of zio.Has here

when setting a breakpoint there I can see there 2 sets, but SttpBackend is a bit different inside (see below). and the exception is thrown throw new Error(s"Defect in zio.Has: ${missingServices} statically known to be contained within the environment are missing")

set:

set = {Set$Set2@3055} "Set$Set2" size = 2
 0 = {LightTypeTag$$anon$1@3063} "package::SttpClientStubbing::Service"
 1 = {LightTypeTag$$anon$1@3064} "SttpBackend[=λ %2:0 → ZIO[-Any,+Throwable,+2:0],+{ZioStreams & package::WebSockets}]"

self.map.keySet:

keySet = {MapOps$ImmutableKeySet@3089} "MapOps$ImmutableKeySet" size = 2
 0 = {LightTypeTag$ParsedLightTypeTag@3087} "package::SttpClientStubbing::Service"
 1 = {LightTypeTag$ParsedLightTypeTag@3088} "SttpBackend[=λ %1:0 → ZIO[-Any,+Throwable,+1:0],+{package::WebSockets & ZioStreams}]"
gchudnov commented 4 years ago

@adamw

hm. just run without zio-test, still the same exception.

created a really simple project that reproduces the problem: https://github.com/gchudnov/zio-sttp-test

-- Wondering if your current code for v3 branch significantly diverged from "3.0.0-RC5" and doesn't have this problem anymore (?)

adamw commented 4 years ago

This is really weird. Indeed, when I copy-paste your code into sttp for a quick test, it works. When I run your project, it fails. And the only changes there were are in docs: https://github.com/softwaremill/sttp/compare/v3.0.0-RC5...master

adamw commented 4 years ago

Ah! It works with zio 1.0.1, but breaks with 1.0.3. So maybe that's a regression in their code? I didn't investigate much further.

While not a fix, it's always a work-around (to use the older zio version)

sttp is still on 1.0.1 because of dotty, I need to upgrade that one day :)

adamw commented 4 years ago

I think that's a binary incompatibility between 1.0.1 and 1.0.3. After updating sttp to 1.0.3, it works again. I'll release RC6 soon with update zio.

gchudnov commented 4 years ago

got it, thank you for the explanation!

guess this issue can be closed.

adamw commented 4 years ago

3.0.0-RC6 is out, please test :)

gchudnov commented 4 years ago

@adamw

yes, it works! thank you very much!