如何用Mockito模拟含内部方法的静态类函数?代码覆盖问题排查
问题分析与解决方案
核心问题
你的代码存在两个关键问题,导致代码覆盖无法命中return hibernateSession.get(Mbc_session.class, sessionGuid);这段逻辑:
HibernateSessionManager的withSession方法使用Consumer<Session>作为参数,而Consumer是无返回值的函数式接口,Lambda中的return语句无法将结果传递出去,导致getMBCSessionByGuid方法实际返回null(测试中的assertNull通过也验证了这一点)。- 测试中的Mock配置和断言逻辑与实际业务逻辑不匹配,没有触发Lambda中的核心执行路径。
具体修复步骤
1. 修复withSession方法签名
将withSession从接受Consumer改为接受Function,支持返回值传递:
public <T> T withSession(Function<Session, T> task) { Session hibernateSession = getSession(); try { return task.apply(hibernateSession); } finally { HibernateSessionManager.current.closeSession(hibernateSession); } }
2. 调整getMBCSessionByGuid方法
适配新的withSession方法,确保Lambda的返回值能被正确返回:
public Mbc_session getMBCSessionByGuid(String sessionGuid) { try { return HibernateSessionManager.current.withSession(hibernateSession -> hibernateSession.get(Mbc_session.class, sessionGuid) ); } catch (Exception e) { logger.error().logFormattedMessage(Constants.MBC_SESSION_GET_ERROR_STRING, e.getMessage()); throw new DAOException(ErrorCode.MBC_1510.getCode(), ErrorCode.MBC_1510.getErrorMessage() + ",Operation: getMBCSessionByGuid"); } }
3. 更新测试初始化的Mock配置
修改initMocks中针对withSession的Mock设置,适配Function类型:
public static void initMocks(Session session) { HibernateSessionManager.current = mock(HibernateSessionManager.class, Mockito.RETURNS_DEEP_STUBS); HibernateTransactionManager.current = mock(HibernateTransactionManager.class, Mockito.RETURNS_DEEP_STUBS); doCallRealMethod().when(HibernateTransactionManager.current).withTransaction(any(), any()); // 适配Function类型的withSession方法 doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Function.class)); when(HibernateSessionManager.current.getSession()).thenReturn(session); }
4. 修正测试用例的断言逻辑
现在方法应该返回预期的Mbc_session对象,替换原有的assertNull:
@Test public void test_getMBCSessionByGuid() { Mbc_session mbcSession = new Mbc_session(); String sessionGuid = "session GUID"; when(HibernateSessionManager.current.getSession()).thenReturn(session); when(session.get(Mbc_session.class, sessionGuid)).thenReturn(mbcSession); Mbc_session mbcSession2 = mbc_sessionDao.getMBCSessionByGuid(sessionGuid); assertEquals(mbcSession, mbcSession2); }
修复原理
修改后,withSession会执行Lambda中的hibernateSession.get(...)并返回结果,getMBCSessionByGuid能正确接收该结果返回,测试用例也会触发完整的执行路径,代码覆盖工具就能检测到这段逻辑的执行。
内容的提问来源于stack exchange,提问作者Bibek Shakya
相关产品推荐
相关产品推荐

