Mockito无法替换getCurrentSession方法返回值问题求助
解决Mockito模拟SessionManager未生效的问题
看起来你碰到了Mockito模拟失效的典型坑,我来帮你拆解下可能的原因和对应的解决办法:
1. 最核心的原因:被测对象没用到你的Mock实例
你在测试类里创建了SessionManager的Mock对象,但如果你要测试的那个类(比如依赖SessionManager的业务类)里的SessionManager是自己new出来的,或者没有和这个Mock实例绑定,那Mockito的模拟肯定不会生效——被测类用的还是真实的SessionManager对象,自然会执行真实方法。
举个反面例子,如果你的业务类是这样写的:
public class MyBusinessService { // 这里直接new了真实对象,Mock根本插不进来 private SessionManager sessionManager = new SessionManager(); public MyClassSessionI doBusiness() throws MyException { return sessionManager.getCurrentSession(...); } }
解决办法:让业务类的依赖可注入,比如用构造方法注入:
public class MyBusinessService { private final SessionManager sessionManager; // 通过构造方法传入SessionManager,方便测试时注入Mock public MyBusinessService(SessionManager sessionManager) { this.sessionManager = sessionManager; } public MyClassSessionI doBusiness() throws MyException { return sessionManager.getCurrentSession(...); } }
然后在测试类的init方法里,把Mock的SessionManager注入到被测对象中:
private MyBusinessService myBusinessService; // 被测对象 private SessionManager sessionManager; @Before public void init () { sessionManager = Mockito.mock(SessionManager.class); // 把Mock实例注入到被测业务类 myBusinessService = new MyBusinessService(sessionManager); Mockito.when(sessionManager.getCurrentSession(any(), anyInt())) .thenReturn(new MyClassSession(1, 20171111, "cash_user")); }
2. 参数匹配器的潜在问题
你用了any()和anyInt()作为参数匹配器,要注意两个点:
- 确保导入的是Mockito的匹配器:
import org.mockito.ArgumentMatchers.*;(如果导错了其他框架的匹配器,会导致匹配失败,Mockito就会执行真实方法) - 如果方法调用时的参数类型和匹配器不兼容,也会触发真实方法。比如
bridgeConfig参数是BridgeConfigI的实现类,用any(BridgeConfigI.class)会比泛化的any()更稳妥。
可以加个验证步骤确认Mock方法是否被调用:
@Test public void testSessionMock() throws MyException { // 调用被测方法 myBusinessService.doBusiness(); // 验证getCurrentSession是否被调用过 Mockito.verify(sessionManager, Mockito.times(1)) .getCurrentSession(any(BridgeConfigI.class), anyInt()); }
如果验证失败,说明方法根本没走到Mock的实例上,回到第一个原因重点排查。
3. 检查方法/类是否为final
如果SessionManager类是final的,或者getCurrentSession方法是final的,Mockito默认无法模拟(因为Mockito基于动态代理实现,final方法不会被代理拦截)。
解决办法:引入Mockito-inline扩展来支持模拟final类/方法。
- Maven依赖:
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-inline</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency>
- Gradle依赖:
testImplementation 'org.mockito:mockito-inline:4.8.1'
内容的提问来源于stack exchange,提问作者drakonchik20
相关产品推荐
相关产品推荐

