我找不到任何关于如何创建 IO tapir 端点存根的方法。在文档 https://tapir.softwaremill.com/en/latest/testing.html 中,我只能看到 scala Future 的示例。基本上我需要创建一个 st...
我找不到任何关于如何创建 IO tapir 端点存根的方法。在文档 https://tapir.softwaremill.com/en/latest/testing.html 中,我只能看到 scala Future 的示例。
基本上我需要为 tapir 端点创建一个存根
endpoint
.post
.in("v1" / "payment")
.securityIn(auth.basic[UsernamePassword]())
.in(jsonBody[HttpPaymentRequest])
.out(jsonBody[HttpPaymentResponse])
.errorOut(oneOf[StatusError](
oneOfVariant(statusCode(StatusCode.BadRequest) and jsonBody[Status400Error]),
oneOfVariant(statusCode(StatusCode.InternalServerError) and jsonBody[Status500Error]),
oneOfVariant(statusCode(StatusCode.Unauthorized) and jsonBody[Unauthorized])
))
.serverSecurityLogic[Unit, IO](basicAuth(secretLocal))
.serverLogic(_ => request => ???)
在两个不同的测试中测试身份验证逻辑和服务器逻辑
val backendStub: SttpBackend[Future, Any] = TapirStubInterpreter(SttpBackendStub.asynchronousFuture)
.whenServerEndpoint(someServerEndpoint)
.thenRunLogic()
.backend()
此示例仅适用于 Future
如果有人有猫IO的例子,请帮忙
以下是使用 ScalaTest 的示例测试:
//> using dep com.softwaremill.sttp.tapir::tapir-cats-effect:1.11.2
//> using dep com.softwaremill.sttp.tapir::tapir-sttp-stub-server:1.11.2
//> using dep com.softwaremill.sttp.tapir::tapir-cats:1.11.2
//> using dep com.softwaremill.sttp.client3::core:3.9.7
//> using dep org.scalatest::scalatest:3.2.19
package sttp.tapir.examples.testing
import cats.effect.IO
import org.scalatest.flatspec.AsyncFlatSpec
import org.scalatest.matchers.should.Matchers
import sttp.client3.*
import sttp.client3.testing.SttpBackendStub
import sttp.tapir.*
import sttp.tapir.integ.cats.effect.CatsMonadError
import sttp.tapir.server.ServerEndpoint
import sttp.tapir.server.stub.TapirStubInterpreter
import scala.concurrent.Future
class CatsServerStubInterpreter extends AsyncFlatSpec with Matchers:
it should "run greet users logic" in {
// given
// We need to pass an SttpBackendStub which is configured for the IO effect. One way to do it is to pass a
// MonadError implementation, as here. Alternatively, you can use any sttp-client cats-effect backend, and obtain
// the stub using its .stub method. For example: AsyncHttpClientCatsBackend.stub[IO]
val stubBackend: SttpBackend[IO, Any] = TapirStubInterpreter(SttpBackendStub[IO, Any](CatsMonadError()))
.whenServerEndpoint(UsersApi.greetUser)
.thenRunLogic()
.backend()
// when
val response = sttp.client3.basicRequest
.get(uri"http://test.com/api/users/greet")
.header("Authorization", "Bearer password")
.send(stubBackend)
// then
// since we are using ScalaTest, we need to run the IO effect, here - synchronously. When using an IO-aware test
// framework, this might get simplified.
import cats.effect.unsafe.implicits.global
response.unsafeRunSync().body shouldBe Right("hello user123")
}
// The API under test
object UsersApi:
val greetUser: ServerEndpoint[Any, IO] = endpoint.get
.in("api" / "users" / "greet")
.securityIn(auth.bearer[String]())
.out(stringBody)
.errorOut(stringBody)
.serverSecurityLogic(token => IO(if token == "password" then Right("user123") else Left("unauthorized")))
.serverLogic(user => _ => IO(Right(s"hello $user")))