如何为WebFlux函数式路由透传服务设计合理的测试方案
问题原因分析
首次测试失败的根本原因
- 路由配置中注册的处理器方法是
handler::doPassthru,但你Mock的是handler.passthru方法,方法名不匹配导致Mock规则未生效,调用的是真实的处理器逻辑 - 你Stub返回的响应体为
AccessTokens类型,但测试断言时尝试将响应体转换为AuthRequest做相等校验,类型完全不匹配自然返回失败。
现有测试方案评价
你当前使用MockWebServer + WebTestClient的方案是透传类网关服务的标准集成测试方案,已经可以覆盖核心的请求转发、响应透传逻辑,比单纯Mock处理器的单元测试更贴合实际运行逻辑,能真实验证路由匹配、WebClient调用、响应封装全链路流程,是该场景下的最优方向,只需要补充几个测试点即可实现全场景覆盖:
- 验证请求透传完整性:调用
mockBackEnd.takeRequest()获取Mock后端收到的真实请求,校验请求方法、路径、Header、请求体与你发出的请求完全一致 - 覆盖异常响应透传场景:Mock返回4xx、5xx状态码的响应,校验透传服务是否原样返回状态码、响应头、响应体
- 覆盖全量请求方法场景:补充GET、DELETE等无请求体的请求测试,避免
PooledDataBuffer读取空请求体出现异常 - 验证Header透传逻辑:请求端携带自定义Header,校验Mock后端能收到对应Header;Mock响应携带自定义Header,校验透传服务返回的响应也包含对应Header
请求校验示例代码补充
// 在现有测试逻辑末尾追加请求校验逻辑 RecordedRequest recordedRequest = mockBackEnd.takeRequest(); // 校验请求方法 assertThat(recordedRequest.getMethod()).isEqualTo(HttpMethod.POST.name()); // 校验请求路径 assertThat(recordedRequest.getPath()).isEqualTo("/service/auth"); // 校验请求体内容 AuthRequest receivedRequest = objectMapper.readValue(recordedRequest.getBody().readUtf8(), AuthRequest.class); assertThat(receivedRequest.getSecretKey()).isEqualTo("secretKey"); // 校验自定义请求头透传 assertThat(recordedRequest.getHeader("X-Custom-Header")).isEqualTo("testValue");
可选轻量测试方案
如果需要更快的测试执行速度,可以搭配单元测试单独验证RouteHandler逻辑:手动构造ServerRequest,Mock WebClient的返回结果,直接调用处理器方法校验返回值,该方案不需要启动Spring上下文,执行速度更快,但无法覆盖路由匹配逻辑,适合和集成测试搭配使用。
内容的提问来源于stack exchange,提问作者ChambreNoire
相关产品推荐
相关产品推荐

