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

使用Mockito存根跨类调用的方法时返回值不符合预期是什么原因

问题根因
  • 你在测试代码中通过Mockito.spy()生成的B类实例,和A.methodA()内部通过new B()生成的B类实例是完全独立的两个对象
  • Mockito的存根规则仅作用于你主动创建的spy对象,无法自动作用于方法内部新建的B实例,因此调用的还是原生的methodX()逻辑,返回Hello!
解决方案

这里提供两种常用的修复方案:

方案1:调整业务代码实现依赖注入(更推荐,符合可测试设计原则)

修改A类的实现,将B实例的创建逻辑外移,通过参数/构造器注入,避免在方法内部硬编码新建对象:

public class A {
    // 因为methodA是静态方法,直接将B作为方法参数传入即可
    public static String methodA(B b) {
        String x = b.methodX();
        return x + "how are ya?";
    }
}

对应的测试代码调整为:

@Test
public void testGreeting() {
    final B b = Mockito.spy(new B());
    Mockito.when(b.methodX()).thenReturn("Hi!");

    String greetings = A.methodA(b);
    // 此时greetings返回值为 "Hi!how are ya?",符合预期
}

方案2:Mock B类的构造方法(适用于无法修改业务代码的场景)

使用Mockito 3.5+版本提供的mockConstruction方法,控制所有B类实例的创建:

@Test
public void testGreeting() {
    try (MockedConstruction<B> mockedB = Mockito.mockConstruction(B.class, 
        (mock, context) -> Mockito.when(mock.methodX()).thenReturn("Hi!"))) {
        
        String greetings = A.methodA();
        // 此时methodA内部new的B就是你mock的对象,返回值符合预期
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 00:45:04