首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ZIO + HTTP4S中测试我的API时挂起集成测试

在ZIO + HTTP4S中测试我的API时挂起集成测试
EN

Stack Overflow用户
提问于 2022-06-09 20:36:18
回答 1查看 147关注 0票数 1

我在测试我的第一个ZIO+HTTP4S应用程序时遇到了问题。测试挂起,没有完成。

我的应用程序(简化)的代码是

代码语言:javascript
复制
object Main extends App {
  def server: ZIO[AppEnvironment, Throwable, Unit] =
    for {
      (...)
      fullApp <- ZIO.runtime[AppEnvironment].flatMap { implicit rts =>
        BlazeServerBuilder[AppTask](ec)
          .bindHttp(api.port, api.endpoint)
          .withHttpApp(CORS(httpApp))
          .serve
          .compile[AppTask, AppTask, CatsExitCode]
          .drain
      }
    } yield fullApp

  override def run(args: List[String]): ZIO[ZEnv, Nothing, ExitCode] = {
    server.provideSomeLayer[ZEnv](appEnvironment).tapError(err => putStrLn(s"Execution failed with: $err")).exitCode
  }
}

这是我的测试代码。请注意,它基本上是从THIS OTHER STACKOVERFLOW QUESTION复制的。

代码语言:javascript
复制
object ApiTest extends DefaultRunnableSpec {
  val ec: ExecutionContext = ExecutionContext.global
  def httpServer           = Main.run(List()).forkManaged.toLayer

  val clockDuration = ofSeconds(1)
  val blocker       = Blocker.liftExecutionContext(ec)

  //did the httpserver start listening on 8080?
  private def isLocalPortInUse(port: Int): ZIO[Clock, Throwable, Unit] = {
    IO.effect {
        println("checking for local port in use")
        new Socket("0.0.0.0", port).close()
      }
      .retry(Schedule.linear(clockDuration) && Schedule.recurs(10))
  }

  override def spec: ZSpec[Environment, Failure] =
    suite("MainTest")(
      testM("Health check") {
        for {
          _ <- TestClock.adjust(clockDuration).fork
          _ = println("1")
          _ <- isLocalPortInUse(8080)
          _ = println("2")
          client <- Task(JavaNetClientBuilder[Task](blocker).create)
          _ = println("3")
          response <- client.expect[String]("http://localhost:8080/healthcheck")
          _ = println("4")
        } yield assert(response)(equalTo(""))
      }
    ).provideCustomLayerShared(httpServer)
}

问题是,一旦服务器启动,测试就会停止运行,而不会被执行。输出是

代码语言:javascript
复制
1
checking for local port in use
checking for local port in use
<server init message>
In Suite "MainTest", test "Health check" has taken more than 1 m to execute. If this is not expected, consider using TestAspect.timeout to timeout runaway tests for faster diagnostics.

因此,如您所见,测试运行正常,直到服务器启动,然后不再继续执行。

另外,我如何才能执行一个POST电话而不是一个GET电话?我有点迷失在使用http4sClients、ZHTTP、BlazeClientBuilders等的HTTP4S/ZIO生态系统中。在类似上一次测试中,对我的服务器进行POST调用的最简单方法是什么?

干杯!

编辑:我检查了服务器在挂在这里时是否正常工作,我可以从终端执行CURL调用,并且它的响应是正确的。因此,问题似乎很明显,即一旦服务器启动,它就停留在前面,而不是后台,并且测试没有机会完成执行。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-09 23:22:05

您正在将时钟提前1秒,但您的应用程序可能需要更多的时间来运行。另外,您的特定测试将需要无限的时间来运行,因为在ZIO中单元测试是瞬时的,而集成测试则不是。

将单元测试的时间提前1秒理论上需要0秒。这可能不足以使港口获得自由。

由于您正在尝试创建一个集成测试,所以您应该使用一个真正的Clock,而不是测试工具包提供的那个。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72566380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档