You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vertx Web Client测试断言成功但仍超时问题求助

Vert.x Web Client测试GraphQL服务超时问题

问题描述

使用vertx-web-graphql依赖运行GraphQL服务,对该服务进行测试时,vertx-web-client测试始终超时,即使testContext.completeNow()之前的断言并未失败。

在其他Vertx测试中均使用testContext.assertComplete(...).onComplete(...)方式,但在Web Client测试中无效,推测该场景下需要以不同方式完成testContext,但未能找到方法。

版本信息

  • Kotlin (1.7.20)
  • vertx(core、graphql、postgres、web-client、vertx-junit5)(4.3.4)

问题代码

@ExtendWith(VertxExtension::class)
class GraphQlVerticleTest {

    @BeforeEach
    fun `deploy GraphQL Verticle`(vertx: Vertx, testContext: VertxTestContext) {
      vertx.deployVerticle(GraphQlVerticle(setupPostgreSqlClient(vertx), setupJWTAuthenticationProvider(vertx)),
                           testContext.succeedingThenComplete())
    }

    @Test
    fun `Wrong Login Credentials cause Login Failed message`(vertx: Vertx, testContext: VertxTestContext) {
        val webClient: WebClient = WebClient.create(vertx)
      
        testContext.assertComplete(webClient.post(graphQLPort, graphQLHostName, graphQLURI)
                                    .putHeader("Content-Type", "application/json")
                                    .sendJsonObject(createLoginAttemptQueryAsJsonObject(wrongEmail, wrongPassword)))
          .onComplete { asyncResult ->
              assertThat(asyncResult.result().bodyAsString()).isEqualTo(loginFailedResponse)
              println("hello I executed")
              testContext.completeNow()
          }
    }

    @AfterEach
    fun `check that the Verticle is still there`(vertx: Vertx, testContext: VertxTestContext) {
        assertThat(vertx.deploymentIDs()).isNotEmpty.hasSize(1)
    }
}

已尝试方案

曾将断言和testContext完成语句放入testContext.verify {}块,但无效。查阅vertx-junit5和vertx-web-client文档,未找到相关Web Client测试内容,搜索也无有效结果。

预期结果

测试应在断言成功后完成,如同其他Vertx测试一样。


解决方案

问题出在异步测试的回调处理方式上,需要遵循Vert.x JUnit 5的异步测试范式,确保测试上下文被正确标记为完成。

修正后的测试方法

@Test
fun `Wrong Login Credentials cause Login Failed message`(vertx: Vertx, testContext: VertxTestContext) {
    val webClient: WebClient = WebClient.create(vertx)
  
    webClient.post(graphQLPort, graphQLHostName, graphQLURI)
        .putHeader("Content-Type", "application/json")
        .sendJsonObject(createLoginAttemptQueryAsJsonObject(wrongEmail, wrongPassword))
        .onComplete(testContext.succeeding { response ->
            // 用verify块包裹断言,确保在Vert.x事件循环线程安全执行
            testContext.verify {
                assertThat(response.bodyAsString()).isEqualTo(loginFailedResponse)
                println("hello I executed")
            }
            // 明确标记测试完成
            testContext.completeNow()
        })
}

修正后的AfterEach方法

@AfterEach
fun `check that the Verticle is still there`(vertx: Vertx, testContext: VertxTestContext) {
    testContext.verify {
        assertThat(vertx.deploymentIDs()).isNotEmpty.hasSize(1)
    }
    testContext.completeNow()
}

关键说明

  1. 使用testContext.succeeding()作为异步回调,它会自动验证异步操作成功,并在Vert.x事件循环线程中执行后续逻辑,避免线程安全问题。
  2. 将断言放入testContext.verify()块中,确保断言操作受测试上下文管控,避免因线程问题导致的异常。
  3. 在回调逻辑末尾调用testContext.completeNow(),明确告知测试框架测试已完成,避免超时。

内容的提问来源于stack exchange,提问作者Broeckelmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:30:53