如何在mockito中用内部方法模拟静态类函数?

v2g6jxz6  于 2022-11-23  发布在  其他
关注(0)|答案(1)|浏览(148)

我有一个名为HibernateSessionManager类,它具有静态方法

public static HibernateSessionManager current;

我试图嘲弄

public Mbc_session getMBCSessionByGuid(String sessionGuid) { 
  try { 
    return HibernateSessionManager.current.withSession(hibernateSession -> { 
       return 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"); 
 } 
}

我在@before中使用以下函数

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()); 
  doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Consumer.class)); 
  // Mockito.when(HibernateSessionManager.current.withSession((Consumer<Session>) any(Function.class))).thenCallRealMethod(); 
  
  when(HibernateSessionManager.current.getSession()).thenReturn(session); 
}

我的测试用例如下

@Test public void test_getMBCSessionByGuid() { 
  Mbc_session mbcSession = new Mbc_session(); 
  String sessionGuid = "session GUID"; 
  when(HibernateSessionManager.current.getSession()).thenReturn(session); 
  // when(sessionFactory.getCurrentSession()).thenReturn(session); 
  when(session.get(Mbc_session.class, sessionGuid)).thenReturn(mbcSession); 
  Mbc_session mbcSession2 = mbc_sessionDao.getMBCSessionByGuid(sessionGuid); 
  assertNull(mbcSession2); 
}

它已通过,但覆盖率未触及以下代码

return hibernateSession.get(Mbc_session.class, sessionGuid);

这是我的withSession代码

public void withSession(Consumer<Session> task) { 
     Session hibernateSession = getSession(); 
     try { 
        task.accept(hibernateSession); 
      } finally { 
        HibernateSessionManager.current.closeSession(hibernateSession); 
     } 
}

打开会话

public Session getSession() { 
    Session threadCachedSession = threadSession.get(); 
    if (threadCachedSession != null) { 
       if (!threadCachedSession.isOpen()) { throw new 
          IllegalStateException("Session closed outside of 
           HibernateSessionManager."); 
       } 
       return threadCachedSession; 
     } return sessionFactory.openSession(); 

   }
xdnvmnnf

xdnvmnnf1#

查看代码并假设它可以编译,我认为问题在于您有两个withSession(...)方法,而在发布的代码中,您试图模拟错误的方法。下面是它们的签名:

// You should NOT mock this one
void withSession(Consumer<Session> task) {
  ...
}

// You should mock this one instead
Mbc_session withSession(Function<Session, Mbc_session> task) {
  ...
}

很容易猜出来,因为getMBCSessionByGuid方法包含下面的代码片段,其中Function<Session, Mbc_session>作为参数传递给withSession(...),而不是Consumer<Session>

return HibernateSessionManager.current.withSession(hibernateSession -> { 
   // something is returned which means a Function is passed, not a Consumer
   return hibernateSession.get(Mbc_session.class, sessionGuid); 
});

作为一个简单的修复方法,您可以将以下内容添加到测试中:

doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Function.class));

并使用Consumer

doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Consumer.class));

为了以防万一,我可以很容易地在我的机器上重现这个问题。

相关问题