I have a class name HibernateSessionManager which have static method
public static HibernateSessionManager current;
I trying to mock
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"); } }
i am using following function in @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); }
My test case is following
@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); }
it passed but coverage is not touching following code
return hibernateSession.get(Mbc_session.class, sessionGuid);
here is my withSession
code
public void withSession(Consumer<Session> task) { Session hibernateSession = getSession(); try { task.accept(hibernateSession); } finally { HibernateSessionManager.current.closeSession(hibernateSession); } }
openSession
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(); }
Advertisement
Answer
Looking at the code and assuming it compiles, I believe the problem is that you have two withSession(...)
methods and in the code posted you are trying to mock the wrong one. Here are their signatures:
// 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) { ... }
It was easy to guess as the getMBCSessionByGuid
method contains the snippet below with the Function<Session, Mbc_session>
being passed as an argument to withSession(...)
instead of 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); });
As an easy fix, you can just add the following to the test:
doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Function.class));
and remove the existing mock configuration with a Consumer
:
doCallRealMethod().when(HibernateSessionManager.current).withSession(any(Consumer.class));
P.S. Just in case, I can easily reproduce the issue on my machine.