Quarkus与Keycloak升级后JUnit测试出现RoutingContext空指针错误求助
Quarkus/Keycloak升级后自定义认证机制测试出现NullPointerException(RoutingContext为null)
问题分析
升级Quarkus到3.6.4、Keycloak到23.0.4后,自定义认证机制的JUnit测试在awaitItem()步骤抛出NPE,原因是测试中mock的RoutingContext未覆盖内部逻辑新增的get(String)调用,导致返回null触发异常。旧版本偶尔失败的原因是该调用并非必走流程,升级后逻辑变更使其成为必填环节。
解决步骤
1. 定位缺失的mock调用
先捕获RoutingContext.get(String)的所有调用,明确需要mock的key:
// 在测试中添加这段代码,运行后查看控制台输出的key Mockito.when(routingContext.get(Mockito.anyString())).thenAnswer(invocation -> { String key = invocation.getArgument(0); System.out.println("RoutingContext.get called with key: " + key); return null; });
2. 针对性mock必要的key值
根据控制台输出的key,补充对应的mock逻辑。比如如果是多租户相关的租户ID,添加:
// 假设需要获取"basic"租户ID Mockito.when(routingContext.get("quarkus.oidc.tenant")).thenReturn("basic");
如果有其他key,根据CustomAuthenticationMechanism的业务逻辑返回对应的值,比如安全上下文、请求属性等。
3. 优化测试方案(可选)
纯Mockito mock容易遗漏内部依赖,可改用Quarkus原生测试工具贴近真实环境:
@Test void authenticate() { String password = System.getProperty("jdoe-password"); String b64Auth = Base64.encode(("jdoe:"+password).getBytes(StandardCharsets.UTF_8)); given() .header(HttpHeaders.AUTHORIZATION, "Basic " + b64Auth) .when().get("/your-protected-api-path") // 替换为你的受保护接口 .then() .statusCode(200); }
4. 验证多租户配置生效
确保测试环境加载了"basic"租户的正确配置:
- 使用
@TestProfile指定测试专属配置文件 - 在
application-test.properties中配置:quarkus.oidc.tenant.basic.grant-type=password quarkus.oidc.tenant.basic.auth-server-url=... # 其他必要的租户配置
5. 检查异步逻辑处理
确认CustomAuthenticationMechanism中的异步操作(Uni)没有未处理的异常,确保authenticate方法返回的Uni能正确完成。
内容的提问来源于stack exchange,提问作者Anthony Heaney
相关产品推荐
相关产品推荐

