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

如何使用Mockito对类属性的方法调用执行mock操作?

问题根本原因

你写的测试代码不生效,是因为MyClass构造方法内部直接new了真实的OtherClass实例,myClass.other是普通的真实对象,而非Mockito生成的Mock/Spy对象,Mockito无法拦截真实对象的方法调用,所以打桩逻辑不会生效,会走真实的sendRequest()逻辑。


解法1:重构代码使用依赖注入(最佳实践)

优先调整原类的构造逻辑,把依赖从外部传入,从根源上解决可测试性问题,同时不会破坏原有逻辑的兼容性:

public class MyClass {
    protected OtherClass other;

    // 新增依赖注入构造方法,专门用于测试/框架注入
    public MyClass(OtherClass other) {
        this.other = other;
    }

    // 保留原有构造方法,保证业务侧使用兼容
    public MyClass(String arg) {
        this.other = new OtherClass(arg);
    }

    public void doSomething() {
        String response = other.sendRequest();
        // ...
    }
}

对应的测试代码:

// JUnit5需要加这个注解启用Mockito支持,JUnit4用@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
public class MyClassTest {
    @Mock
    private OtherClass other;

    @Test
    public void doSomethingTest() {
        // 直接传入Mock对象构造MyClass
        MyClass myClass = new MyClass(other);
        when(other.sendRequest()).thenReturn("response");
        
        myClass.doSomething();
        // 后续补充你需要的断言逻辑
    }
}

解法2:不修改原代码,通过反射替换依赖

如果无法改动原MyClass的代码,可以通过反射手动把实例内的other字段替换为Mock对象:

@ExtendWith(MockitoExtension.class)
public class MyClassTest {
    @Test
    public void doSomethingTest() throws NoSuchFieldException, IllegalAccessException {
        MyClass myClass = new MyClass("test");
        // 构造Mock的OtherClass对象并打桩
        OtherClass mockOther = Mockito.mock(OtherClass.class);
        when(mockOther.sendRequest()).thenReturn("response");

        // 反射修改protected字段的值
        Field otherField = MyClass.class.getDeclaredField("other");
        otherField.setAccessible(true);
        otherField.set(myClass, mockOther);

        myClass.doSomething();
        // 后续补充你需要的断言逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:30:04