Mockito未Stub目标方法,反而执行了EncService.callFn实际逻辑
解决Mockito模拟EncService.callFn方法时实际逻辑被执行的问题
问题核心原因
你遇到的问题根源在于ServiceClass的sendPayload方法内部直接new了EncService实例,而非通过依赖注入获取实例。Mockito的@Mock和@InjectMocks仅能作用于通过构造器、setter或字段注入的依赖对象,对于方法内直接new出来的对象,Mockito无法拦截替换,导致测试类中模拟的encService和实际代码使用的是两个完全独立的对象,模拟自然失效,实际逻辑会被执行。
解决方案
方案1:修改ServiceClass,采用依赖注入(推荐)
重构ServiceClass,将EncService作为类的依赖,而非在方法内创建实例,最常用的方式是构造器注入:
public class ServiceClass { private final EncSercice encService; // 通过构造器注入依赖 public ServiceClass(EncSercice encService) { this.encService = encService; } public void sendPayload(final ValidRequest req) { // some code imp.. // 使用注入的encService实例,不再手动new String str = encService.callFn(req, keys); } }
方案2:调整测试类,确保Mock对象被正确注入
修改后的ServiceClass会通过构造器接收EncService实例,此时测试类的@InjectMocks会自动将@Mock创建的encService注入到ServiceClass中。若使用JUnit 5,推荐用@ExtendWith(MockitoExtension.class)替代手动初始化Mock:
import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.junit.jupiter.api.extension.ExtendWith; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) public class ClassA { @Mock EncSercice encService; @InjectMocks ServiceClass service; @Test public void testEncryptRegisterTransactionPayload() { ValidRequest request = new ValidRequest(); try { when(encService.callFn(anyString(), any(String[].class))) .thenReturn("Stubbed encrypted message"); service.sendPayload(request); verify(encService).callFn(anyString(), any(String[].class)); } catch (Exception e) { e.printStackTrace(); } } }
方案3:临时方案(不推荐):使用PowerMock拦截new操作
若无法修改ServiceClass代码,可通过PowerMock拦截方法内的new操作,强制返回Mock对象。但该方式会修改字节码,增加测试维护成本,仅作为临时解决方案:
// 需引入PowerMock相关依赖 @RunWith(PowerMockRunner.class) @PrepareForTest(ServiceClass.class) public class ClassA { @Mock EncSercice encService; @InjectMocks ServiceClass service; @Test public void testEncryptRegisterTransactionPayload() throws Exception { ValidRequest request = new ValidRequest(); // 拦截ServiceClass内new EncSercice()的操作,返回Mock对象 whenNew(EncSercice.class).withNoArguments().thenReturn(encService); when(encService.callFn(anyString(), any(String[].class))) .thenReturn("Stubbed encrypted message"); service.sendPayload(request); verify(encService).callFn(anyString(), any(String[].class)); } }
内容的提问来源于stack exchange,提问作者orange_ball_ss
相关产品推荐
相关产品推荐

