Запросы потока модульного теста с помощью SttpBackendStub

У меня есть запрос, который возвращает исходный поток, который я хочу протестировать, например:

/* class */
import sttp.client._

class HttpClient()
                (implicit sttpBackend: SttpBackend[Future, Source[ByteString, Any], Nothing]) {
  /** Start a download stream for large files */
  def downloadStream(url: String): Future[Response[Either[String, Source[ByteString, _]]]] = {
    request
      .get(uri"url")
      .response(asStream[Source[ByteString, Any]])
      .send()
  }
}
/* test */
import org.scalatest.FlatSpec
import org.scalatest.Matchers

class HttpClientSpec extends FlatSpec with Matchers {
  implicit val as = ActorSystem()
  implicit val mat = ActorMaterializer()
  implicit val ex = as

  "downloadStream" should "get a file stream from url" in {
    val url = s"http://example.com/api/v1/file/Test.txt"
    val body = "abcdefghijklmnopqrstuzwxyz"
    val expectedStream = Source.single[ByteString](body.getBytes)

    implicit val stubBackend = SttpBackendStub.asynchronousFuture
      .whenRequestMatches(req => req.method.method == "GET" && req.uri == uri"$url")
      .thenRespond(
        Response(Right(expectedStream), StatusCode.Ok)
      )

    val httpTest = new HttpClient()

    val response = Await.result(httpTest.downloadStream(url), 5.seconds)
    response.body.right.get should be(expectedStream)
  }
}

Но это не удается, потому что SttpBackendStub.asynchronousFuture не обрабатывает потоковые ответы.

type mismatch;
[error]  found   : sttp.client.testing.SttpBackendStub[scala.concurrent.Future,Nothing]
[error]  required: sttp.client.SttpBackend[scala.concurrent.Future,akka.stream.scaladsl.Source[akka.util.ByteString,Any],Nothing]

Как я могу использовать SttpBackendStub, не прибегая к чему-то вроде scalamock?

1 ответ

Просто нужно создать свой собственный класс-заглушку, который extends ожидаемый тип ответа:

class StreamHttpStub
    extends SttpBackendStub[Future, Source[ByteString, Any]](new FutureMonad(), PartialFunction.empty, None) {
}

implicit val stubBackend = new StreamHttpStub()
  .whenRequestMatches(req => req.method.method == "GET" && req.uri == uri"$url")
  .thenRespond(
    Response(Right(expectedStream), StatusCode.Ok)
  )
Другие вопросы по тегам