如何在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
相关产品推荐
相关产品推荐

