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

单元测试中URI.getAuthority()始终返回null:80问题排查

问题根因

核心问题出在DefaultServiceInstance的使用方式上,和过滤逻辑、FilteringDiscoveryClient的核心流程无关:

  • Spring Cloud Commons的DefaultServiceInstance内部不会直接存储通过setUri()传入的URI对象,而是拆分存储scheme、host、port等独立字段,getUri()方法是运行时基于这些字段重新拼接生成URI。
  • 空参构造的DefaultServiceInstance实例,host默认值为null,port默认值为80。你直接调用setUri()传入自定义URI时,方法不会自动解析URI填充host、port、scheme字段。
  • 你在setUp阶段调试看到URI正常,是因为当时查看的是自己手动创建的原始实例;而SimpleDiscoveryClient初始化时会基于传入实例的host、port等字段重新构造服务实例对象,不会读取你手动set的URI值,最终返回到过滤器的实例URI拼接结果为http://null:80/xxx,调用getAuthority()自然返回null:80,导致过滤判断失效。

代码里还存在两个不影响当前报错但会留隐患的问题:

  • FilteringDiscoveryClient构造方法的参数校验有笔误:第二行Assert.notNull()第一个参数传的还是delegate,不是filter,传入null filter时校验不会生效,会触发空指针。
  • 就算URI配置正确,用getAuthority()做判断也有兼容问题:如果服务使用非默认端口,authority会携带端口后缀(比如my.service.id.1:8080),equals判断会失效。
修复方案

1. 修正服务实例初始化方式

不要用空参构造+setUri的方式创建实例,改用全参构造或Builder模式,确保host、port字段被正确赋值:

// 全参构造示例
DefaultServiceInstance testInstance1_1 = new DefaultServiceInstance(
    "ins1_1",
    "my.service.id.1",
    "my.service.id.1",
    80,
    false,
    Map.of()
);
// Builder模式示例,可读性更好
DefaultServiceInstance testInstance1_2 = DefaultServiceInstance.builder()
    .serviceId("my.service.id.1")
    .host("my.service.id.1")
    .port(80)
    .build();
// 其余三个实例按相同逻辑初始化即可

2. 修正参数校验笔误

把构造方法中第二个断言的入参改为filter:

public FilteringDiscoveryClient(DiscoveryClient delegate, Predicate<ServiceInstance> filter) {
    Assert.notNull(delegate, "delegate must not be null");
    Assert.notNull(filter, "filter must not be null"); // 原来这里错传了delegate
    this.delegate = delegate;
    this.filter = filter;
}

3. 优化过滤判断逻辑

优先用ServiceInstance自带的getHost()方法做判断,避免URI解析带来的兼容问题:

FilteringDiscoveryClient client = new FilteringDiscoveryClient(
    mockClient,
    i -> !i.getHost().equals("my.service.id.1")
);

修正后重新运行测试,实例URI会被正确构造,过滤逻辑正常生效,断言可顺利通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 23:24:15