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

如何在Mockito中针对MyServiceClass作用域单独mock getId()方法

用Mockito实现指定类作用域内的方法Mock

嘿,完全懂你的需求——你想让getId()方法只在MyServiceClass的getClassObjects()方法调用时返回指定值,其他类调用这个方法时则能自由设置不同的Mock返回结果。下面就用Mockito来实现这个需求,一步步来:

核心思路

我们需要针对MyServiceClass内部拿到的ParentObject实例做专属Mock,确保只有这个实例的getId()返回我们指定的值;其他类使用的ParentObject实例则完全独立,可以单独设置Mock结果。

方案一:处理静态创建实例的场景

如果OtherClassObject是通过静态方法createOtherClassObject()创建的(就像你示例里的那样),我们可以用Mockito的静态Mock特性来实现局部作用域的控制:

测试代码示例

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

class MyServiceClassTest {

    @Test
    void testGetClassObjects() {
        // 1. 为MyServiceClass专属Mock ParentObject,指定getId返回值
        ParentObject myServiceParentMock = mock(ParentObject.class);
        when(myServiceParentMock.getId()).thenReturn("专属MockID-仅MyService用");

        // 2. Mock OtherClassObject,让它返回上面的专属ParentObject
        OtherClassObject otherClassMock = mock(OtherClassObject.class);
        when(otherClassMock.getParentObject()).thenReturn(myServiceParentMock);

        // 3. 静态Mock create方法,仅在当前测试方法的作用域内生效
        try (MockedStatic<OtherClassObject> mockedStatic = mockStatic(OtherClassObject.class)) {
            // 拦截静态方法,让它返回我们Mock好的OtherClassObject
            mockedStatic.when(OtherClassObject::createOtherClassObject).thenReturn(otherClassMock);

            // 执行MyServiceClass的方法
            MyServiceClass service = new MyServiceClass();
            String result = service.getClassObjects();

            // 验证结果符合预期
            assert result.equals("专属MockID-仅MyService用");
        }
        // 静态Mock会在try代码块结束后自动失效,其他地方调用create方法会走真实逻辑

        // --- 测试其他类调用getId的场景 ---
        ParentObject otherClassParentMock = mock(ParentObject.class);
        when(otherClassParentMock.getId()).thenReturn("其他类用的MockID");
        // 这里可以把这个Mock实例注入到其他类中,验证返回值是我们设置的"其他类用的MockID"
    }
}

关键细节

  • 静态Mock的作用域控制:用try-with-resources包裹MockedStatic,确保静态Mock只在try块内生效,离开这个块后,createOtherClassObject()就会恢复真实实现,不会干扰其他测试或类的调用。
  • 实例隔离:给MyServiceClass用的ParentObject是单独Mock的实例,和其他类使用的Mock实例完全独立,各自的getId()返回值互不影响。

方案二:处理依赖注入的场景

如果OtherClassObject是通过依赖注入(比如Spring的@Autowired)进入MyServiceClass的,那用@InjectMocks和@Mock可以更简洁地实现需求:

测试代码示例

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class MyServiceClassTest {

    // Mock OtherClassObject,会被注入到MyServiceClass中
    @Mock
    private OtherClassObject otherClassObject;

    // 为MyServiceClass专属Mock ParentObject
    @Mock
    private ParentObject parentObject;

    // 把Mock的依赖注入到MyServiceClass实例中
    @InjectMocks
    private MyServiceClass myServiceClass;

    @Test
    void testGetClassObjects() {
        // 设置仅MyServiceClass使用的getId返回值
        when(parentObject.getId()).thenReturn("专属MockID-仅MyService用");
        when(otherClassObject.getParentObject()).thenReturn(parentObject);

        String result = myServiceClass.getClassObjects();
        assert result.equals("专属MockID-仅MyService用");
    }

    @Test
    void testOtherClassUseGetId() {
        // 在其他测试中,完全可以创建新的Mock实例,设置不同的返回值
        ParentObject anotherParentMock = mock(ParentObject.class);
        when(anotherParentMock.getId()).thenReturn("其他类用的MockID");
        // 这里可以将这个实例注入到其他类,验证返回值符合预期
    }
}

这种方式下,@InjectMocks会把我们Mock的otherClassObject注入到MyServiceClass里,只有这个注入的实例会返回我们指定的getId()值;其他类使用的ParentObject实例完全独立,想设置什么返回值都可以。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:49:42