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() }
关键说明
- 使用
testContext.succeeding()作为异步回调,它会自动验证异步操作成功,并在Vert.x事件循环线程中执行后续逻辑,避免线程安全问题。 - 将断言放入
testContext.verify()块中,确保断言操作受测试上下文管控,避免因线程问题导致的异常。 - 在回调逻辑末尾调用
testContext.completeNow(),明确告知测试框架测试已完成,避免超时。
内容的提问来源于stack exchange,提问作者Broeckelmann
相关产品推荐
相关产品推荐

