Java11→17/SpringBoot2→3迁移后Mockito Mock对象NPE问题求助
解决Tracer Mock对象traceContextBuilder()返回null的问题
核心解决方案:显式指定方法返回Mock对象
Mockito 默认对接口的非基本类型方法返回 null,所以你需要手动配置 traceContextBuilder() 方法返回一个非空的 TraceContext.Builder Mock 对象,同时处理链式调用的后续方法:
// 1. 先Mock TraceContext.Builder对象 TraceContext.Builder mockTraceContextBuilder = Mockito.mock(TraceContext.Builder.class); // 2. 配置Tracer的traceContextBuilder()返回这个Mock Builder Mockito.when(tracer.traceContextBuilder()).thenReturn(mockTraceContextBuilder); // 3. 处理链式调用:让builder的方法返回自身(保证链式调用不中断) Mockito.when(mockTraceContextBuilder.traceId(Mockito.anyString())).thenReturn(mockTraceContextBuilder); // 按需配置build()方法返回Mock的TraceContext Mockito.when(mockTraceContextBuilder.build()).thenReturn(Mockito.mock(TraceContext.class));
针对你其他问题的解答:
能否初始化Mock时让所有参数/返回值非空?
可以用@Mock(answer = Answers.RETURNS_DEEP_STUBS)注解,它会自动为嵌套调用的方法生成Mock对象,避免返回null。但这种方式不推荐作为常规操作——自动生成的深层Mock会让测试逻辑变得模糊,难以追踪依赖,建议只在简单场景下使用,优先显式配置需要的方法返回值。是否需要使用@Spy注解?
不需要。@Spy是用来做「部分Mock」的,它基于真实对象,只替换部分方法的行为。而Tracer是接口,没有可直接实例化的默认实现(或实例化需要大量依赖),用@Mock更合适。能否创建具备真实对象所有可用字段的Mock?
Mock对象是模拟出来的代理,不会拥有真实对象的字段和完整行为。如果需要真实的业务逻辑,要么用@Spy包装一个可实例化的真实实现(前提是该实现无复杂依赖),要么自己写一个Stub类实现Tracer接口。但测试中通常只需要模拟当前用例依赖的方法,不需要完整复刻真实对象。
内容的提问来源于stack exchange,提问作者Juan Pereyra
相关产品推荐
相关产品推荐

