You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

在调用层级中插入Mock对象:Mockito单元测试咨询

如何在多层调用链中使用Mockito模拟ClassC.methodC

没问题,我来帮你搞定这个多层依赖的Mock场景!你的调用链是ClassA.methodA() → ClassB.methodB() → ClassC.methodC(),我们需要隔离ClassC的实际逻辑,让它返回预设的模拟值,同时测试上层的调用流程。下面是具体的实现步骤和代码示例:

核心思路

我们需要从最底层的依赖(ClassC)开始Mock,然后把这个Mock对象逐层注入到上层的依赖中,最终让待测试的ClassA实例使用配置好的依赖链,这样就能完全控制ClassC的返回值,而不会执行它的实际逻辑。

代码实现(基础版,适合public字段)

假设你的类字段都是public的(就像你给出的代码结构),可以直接手动注入Mock对象:

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

class ClassATest {

    @Test
    void testMethodA() {
        // 1. 创建ClassC的Mock对象
        ClassC mockC = mock(ClassC.class);
        
        // 2. 预设mockC.methodC()的返回值
        Object mockReturnValue = new Object(); // 换成你需要的模拟值
        when(mockC.methodC()).thenReturn(mockReturnValue);
        
        // 3. 创建ClassB实例,并注入mockC
        ClassB b = new ClassB();
        b.c = mockC;
        
        // 4. 创建ClassA实例,并注入配置好的ClassB
        ClassA a = new ClassA();
        a.b = b;
        
        // 5. 执行待测试的方法
        a.methodA();
        
        // 6. 验证mockC的methodC是否被正确调用(可选,但推荐)
        verify(mockC).methodC();
    }
}

更优雅的方式(适合私有字段,使用@InjectMocks)

如果你的ClassB和ClassA中的字段是私有(而非public),可以用Mockito的@InjectMocks@Mock注解自动完成依赖注入,代码会更简洁:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.*;

class ClassATest {

    // 声明需要Mock的底层依赖
    @Mock
    private ClassC mockC;
    
    // 自动将mockC注入到ClassB实例中
    @InjectMocks
    private ClassB b;
    
    // 自动将配置好的b注入到ClassA实例中
    @InjectMocks
    private ClassA a;

    @BeforeEach
    void setUp() {
        // 初始化Mockito注解
        MockitoAnnotations.openMocks(this);
    }

    @Test
    void testMethodA() {
        // 预设mockC的返回值
        Object mockReturnValue = new Object();
        when(mockC.methodC()).thenReturn(mockReturnValue);
        
        // 执行测试方法
        a.methodA();
        
        // 验证调用行为
        verify(mockC).methodC();
    }
}

关键要点解释

  • Mock最底层依赖:我们只需要MockClassC,因为它是实际需要隔离的外部逻辑/依赖,上层的ClassBClassA我们用真实实例(或部分Mock,这里用真实实例更适合测试业务流程)。
  • 逐层注入:必须确保ClassB使用的是我们Mock的ClassCClassA使用的是配置好的ClassB,这样调用链才能走到Mock对象上。
  • 预设返回值when(mockC.methodC()).thenReturn(...)告诉Mockito,当methodC被调用时,返回我们指定的模拟值,而不是执行ClassC中的实际逻辑。
  • 验证调用verify(mockC).methodC()可以确认methodC确实被调用了,保证整个调用链是正常执行的。

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

火山引擎 最新活动