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

JUnit5中Mockito模拟HATEOAS场景时Method空指针异常解决

解决StaticPathLinkBuilder单元测试空指针异常的正确Mock方式

问题根源在于你用@Spy处理静态工具类StaticPathLinkBuilder的方式不对——@Spy仅适用于实例对象的部分Mock,无法覆盖静态方法的行为,导致实际执行时还是走了原方法的逻辑,而原方法内部的method参数未被正确初始化,最终抛出空指针异常。

正确的做法是使用Mockito的静态Mock能力来处理静态方法,具体步骤如下:

1. 依赖版本要求

确保你的Mockito版本在3.4.0及以上,这个版本引入了mockStatic方法,支持通过try-with-resources自动管理静态Mock的生命周期,避免影响其他测试用例。

2. 静态Mock StaticPathLinkBuilder

在测试方法中,用mockStatic创建StaticPathLinkBuilder的静态Mock,同时Mock它返回的LinkBuilder对象,提前Stub好createRelativeUri的行为:

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.mockito.Mockito.*;

class YourTargetTest {

    @Test
    void testSuccessfully() {
        // 1. Mock LinkBuilder,模拟createRelativeUri的返回值
        LinkBuilder mockLinkBuilder = mock(LinkBuilder.class);
        when(mockLinkBuilder.createRelativeUri(anyString()))
            .thenReturn("/mock/relative/uri"); // 替换为你需要的测试用URI

        // 2. 静态Mock StaticPathLinkBuilder,Stub linkTo方法
        try (MockedStatic<StaticPathLinkBuilder> mockedStatic = mockStatic(StaticPathLinkBuilder.class)) {
            // 根据你实际调用的linkTo重载方法,调整参数匹配器
            mockedStatic.when(() -> StaticPathLinkBuilder.linkTo(any(), any()))
                .thenReturn(mockLinkBuilder);

            // 3. 执行被测试的方法
            YourService service = new YourService();
            Object response = service.methodUnderTest();

            // 4. 执行断言逻辑
            // 例如:assertEquals(expectedUri, response.getLinkUri());
        }
    }
}

3. 关键注意事项

  • 匹配正确的linkTo重载:如果你的业务代码调用的是linkTo的其他重载(比如linkTo(Class<?> controllerClass)),需要调整when中的参数匹配器,确保Stub的是实际被调用的方法。
  • 避免静态Mock泄漏:必须用try-with-resources包裹mockStatic,确保测试结束后自动清除静态Mock,防止其他测试用例受到影响。
  • 不要混用实例Mock和静态Mock:StaticPathLinkBuilder是纯静态工具类,不需要也不能用@Spy或@Mock注解处理,必须用静态Mock方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:13:10