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.