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

Mockito:为Spy对象注入Mock,测试A类时Mock其依赖C的D、E

问题背景

现有类结构:

class A {
    B b;  
    C c;  
}

class C {
    D d;  
    E e;  
}

需要为A编写单元测试,要求保留C的真实方法逻辑(不Mock C),但需要Mock C内部的D和E对象。尝试以下三种方案均未生效:

  • 方案1:
@Mock B b;  
@Mock D d;  
@Mock E e;  
@Spy @InjectMocks C c;  
@InjectMocks A a;
  • 方案2:
@Mock B b;  
@Mock D d;  
@Mock E e;   
@Spy C c = Mockito.spy(new C(d,e));  
@InjectMocks A a;
  • 方案3:参考Mockito向Spy对象注入Mock的相关建议
解决方案

方法1:手动注入Mock到Spy实例

先创建C的真实实例,手动注入Mock的D、E后转为Spy,再注入到A中:

@ExtendWith(MockitoExtension.class)
public class ATest {
    @Mock
    private B b;
    @Mock
    private D d;
    @Mock
    private E e;
    
    private C c;
    @InjectMocks
    private A a;
    
    @BeforeEach
    void setUp() {
        // 初始化C真实实例
        c = new C();
        // 手动设置Mock的D、E(如果没有setter,用反射)
        c.setD(d);
        c.setE(e);
        // 转为Spy,保留C的真实方法
        c = Mockito.spy(c);
        // 将Spy的C注入A
        a.setC(c);
    }
    
    @Test
    void testSample() {
        // 配置D的Mock行为
        when(d.someMethod()).thenReturn("mockedValue");
        
        // 执行A的业务方法
        a.execute();
        
        // 验证Mock调用
        verify(d).someMethod();
    }
}

如果C没有公开setter,用反射工具注入:

// 示例:用Mockito的FieldSetter
FieldSetter.setField(c, c.getClass().getDeclaredField("d"), d);
FieldSetter.setField(c, c.getClass().getDeclaredField("e"), e);

方法2:注解配合初始化修正

用注解时,需确保Mock实例先初始化,再注入到C的Spy中:

@ExtendWith(MockitoExtension.class)
public class ATest {
    @Mock
    private B b;
    @Mock
    private D d;
    @Mock
    private E e;
    
    @Spy
    private C c = new C();
    
    @InjectMocks
    private A a;
    
    @BeforeEach
    void setUp() {
        // 重新初始化注解,确保Mock就绪
        MockitoAnnotations.openMocks(this);
        // 反射注入D、E到C的Spy
        FieldSetter.setField(c, c.getClass().getDeclaredField("d"), d);
        FieldSetter.setField(c, c.getClass().getDeclaredField("e"), e);
    }
    
    // 测试方法...
}

失败原因解析

  • 方案1:@Spy与@InjectMocks同用时,Mockito的注入优先级导致D、E的Mock未被注入到C的Spy实例。
  • 方案2:初始化new C(d,e)时,d、e还未被Mockito实例化为Mock(注解初始化有顺序),传入的是null而非有效Mock对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 07:10:32