livestub
With livestub you can easly setup http server that behaves exactly as you would like it to. That makes livestub a perfect solution for faking arbitrary services which might be very useful in development/testing.
Usage
launch
-
coursier
coursier launch com.softwaremill.sttp.livestub:livestub-app_2.13:0.1.10 -- -p 7070
-
docker
docker run -p 7070:7070 softwaremill/sttp.livestub
stub
curl -X POST 'localhost:7070/__set' \
-d '{"when":{"method":"GET", "url":"animals/1/status"}, "then": {"statusCode":200, "body":{"status": "happy"} }}'
invoke
curl 'localhost:7070/animals/1/status'
{"status":"happy"}
swagger
Swagger is available under /__admin/docs
advanced stubbing
Livestub supports wildcard http methods as well as wildcard path parameters.
wildcard method:
curl -X POST 'localhost:7070/__set' \
-d '{"when":{"method":"*", "url":"dogs"}, "then": {"statusCode":200, "body":{"status": "OK"} }}'
wildcard path param:
curl -X POST 'localhost:7070/__set' \
-d '{"when":{"method":"GET", "url":"dogs/*/status"}, "then": {"statusCode":200, "body":{"status": "happy"} }}'
multiwildcard path param: (this one catches all routes which originate from /dogs
)
curl -X POST 'localhost:7070/__set' \
-d '{"when":{"method":"GET", "url":"dogs/**"}, "then": {"statusCode":200, "body":{"status": "cheerful"} }}'
additional methods
clear stubbed routes
curl -X POST 'localhost:7070/__clear'
show stubbed routes
curl 'localhost:7070/__routes'
set many responses which will be cycled through
curl -X POST 'localhost:7070/__set_many' \
-d '{"when":{"method":"GET", "url":"animals/1/status"}, "then": [
{"statusCode":200, "body":{"status": "happy"} },
{"statusCode":200, "body":{"status": "unhappy"} }
]
}'
stubbing from code - sdk
libraryDependencies += "com.softwaremill.sttp.livestub" % "livestub-sdk" % "0.1.10"
Given that very self-explanatory bootstrap:
import cats.effect._
import sttp.client.asynchttpclient.cats.AsyncHttpClientCatsBackend
import sttp.client.asynchttpclient._
import sttp.client.SttpBackend
import scala.concurrent._
import sttp.livestub.sdk._
import sttp.livestub.api._
import sttp.client.{Response => _, _}
import sttp.model._
import io.circe.Json
implicit val cs = IO.contextShift(ExecutionContext.global)
implicit val timer = IO.timer(ExecutionContext.global)
you can stub an arbitrary request:
AsyncHttpClientCatsBackend[IO]().flatMap { implicit backend: SttpBackend[IO, Nothing, WebSocketHandler] =>
val livestub = new LiveStubSdk[IO, Nothing, WebSocketHandler](uri"http://mock:7070")
livestub
.when(RequestStub(MethodValue.Wildcard, "/user/*/status"))
.thenRespond(Response.emptyBody(StatusCode.Ok, List(Header("X-App", "123"))))
}
stub given sttp request:
AsyncHttpClientCatsBackend[IO]().flatMap { implicit backend: SttpBackend[IO, Nothing, WebSocketHandler] =>
val request = basicRequest
.body(Map("name" -> "John", "surname" -> "doe"))
.post(uri"https://httpbin.org/post?signup=123")
val livestub = new LiveStubSdk[IO, Nothing, WebSocketHandler](uri"http://mock:7070")
livestub.when(request).thenRespond(Response(Some(Json.fromString("OK")), StatusCode.Ok))
}
or stub given tapir endpoint:
import sttp.tapir._
AsyncHttpClientCatsBackend[IO]().flatMap { implicit backend: SttpBackend[IO, Nothing, WebSocketHandler] =>
val myEndpoint = endpoint.get.in("/status").out(stringBody)
val livestub = new LiveStubSdk[IO, Nothing, WebSocketHandler](uri"http://mock:7070")
livestub.when(myEndpoint)
.thenRespond(Response.emptyBody(StatusCode.Ok, List(Header("X-App", "123"))))
}