Testing

White box testing

If you are unit testing your application you should stub all external services.

If you are using sttp client to send HTTP requests, and if the externals apis, which yours application consumes, are described using tapir, you can create a stub of the service by converting endpoints to SttpBackendStub (see the sttp documentation for details on how the stub works).

Add the dependency:

"com.softwaremill.sttp.tapir" %% "tapir-sttp-stub-server" % "0.18.0-M8"

And the following imports:

import sttp.client3.testing.SttpBackendStub
import sttp.tapir.server.stub._

Given the following endpoint:

import sttp.tapir._
import sttp.tapir.generic.auto._
import sttp.tapir.json.circe._
import io.circe.generic.auto._

case class ResponseWrapper(value: Double)

val endpoint = sttp.tapir.endpoint
  .in("api" / "sometest4")
  .in(query[Int]("amount"))
  .post
  .out(jsonBody[ResponseWrapper])

Convert any endpoint to SttpBackendStub:

import sttp.client3.monad.IdMonad

val backend = SttpBackendStub
  .apply(IdMonad)
  .whenRequestMatchesEndpoint(endpoint)
  .thenSuccess(ResponseWrapper(1.0))

A stub which executes an endpoint’s server logic can also be created (here with an identity effect, but any supported effect can be used):

import sttp.client3.Identity
import sttp.client3.monad.IdMonad

val anotherBackend = SttpBackendStub
  .apply(IdMonad)
  .whenRequestMatchesEndpointThenLogic(endpoint.serverLogic[Identity](_ => Right(ResponseWrapper(1.0))))

Black box testing

When testing an application as a whole component, running for example in docker, you might want to stub external services with which your application interacts.

To do that you might want to use well-known solutions like e.g. wiremock or mock-server, but if their api is described using tapir you might want to use livestub, which combines nicely with the rest of the sttp ecosystem.