Quarkus测试模式下如何让服务器监听子域名?
解决方案
方案1:通过RestAssured设置Host请求头(无需修改hosts或服务器配置)
不需要让Quarkus服务器监听子域名,直接在RestAssured请求中指定Host头,同时保持baseUri为localhost即可模拟子域名访问:
@QuarkusTest class TestClass { @Test public void someTest() { RestAssured.given().log().all() .baseUri("http://localhost:8081") .basePath("/api") .header("Host", "subdomain.localhost") // 添加Host头模拟子域名请求 .contentType(ContentType.JSON) .accept(ContentType.JSON) .get("/endpoint") .then() .statusCode(200); } }
请求实际连接的是localhost:8081,但服务器会收到Host: subdomain.localhost的请求头,效果和直接用子域名访问完全一致,同时避免了DNS解析异常。
方案2:配置Quarkus测试服务器监听所有地址+JVM进程内DNS映射
如果业务逻辑依赖子域名的实际解析(比如代码中需要读取请求Host),可以按以下步骤操作:
步骤1:让Quarkus测试服务器监听所有地址
在application.properties中添加测试环境专属配置:
%test.quarkus.http.host=0.0.0.0
或者在测试类中通过测试Profile覆盖配置:
@QuarkusTest @QuarkusTestProfile public class TestProfile implements QuarkusTestProfile { @Override public Map<String, String> getConfigOverrides() { return Map.of("quarkus.http.host", "0.0.0.0"); } }
配置后服务器会接受来自任何主机名的请求。
步骤2:JVM进程内临时映射子域名
通过反射修改JVM的本地DNS缓存,仅在当前测试进程生效,无需修改系统hosts:
@BeforeAll static void setupSubdomainMapping() throws Exception { InetAddress localAddress = InetAddress.getByName("127.0.0.1"); // 访问InetAddress的内部hosts映射表 Field hostsField = InetAddress.class.getDeclaredField("hosts"); hostsField.setAccessible(true); @SuppressWarnings("unchecked") Map<String, InetAddress> hostsMap = (Map<String, InetAddress>) hostsField.get(null); hostsMap.put("subdomain.localhost", localAddress); }
方案3:统一配置RestAssured+进程内DNS映射
如果测试中大量用到子域名,可以提前初始化RestAssured配置和DNS映射:
@QuarkusTest class TestClass { static { // 统一设置RestAssured的baseUri RestAssured.baseURI = "http://subdomain.localhost:8081"; // 进程内映射子域名 try { InetAddress localAddress = InetAddress.getByName("127.0.0.1"); Field hostsField = InetAddress.class.getDeclaredField("hosts"); hostsField.setAccessible(true); @SuppressWarnings("unchecked") Map<String, InetAddress> hostsMap = (Map<String, InetAddress>) hostsField.get(null); hostsMap.put("subdomain.localhost", localAddress); } catch (Exception e) { e.printStackTrace(); } } @Test public void someTest() { RestAssured.given().log().all() .basePath("/api") .contentType(ContentType.JSON) .accept(ContentType.JSON) .get("/endpoint") .then() .statusCode(200); } }
内容的提问来源于stack exchange,提问作者Bentz
相关产品推荐
相关产品推荐

