Correct configuration to mock Hibernate's sessionFactory.getCurrentSession()

Viewed 2649

I have the following:

@Repository
@Transactional
@HibernateProfile
public class PersonaHibernateRepository implements PersonaRepository {

    private static final Logger logger = LoggerFactory.getLogger(PersonaHibernateRepository.class.getSimpleName());

    private final SessionFactory sessionFactory;

    public PersonaHibernateRepository(SessionFactory sessionFactory){
        logger.info("{} constructor", PersonaHibernateRepository.class.getSimpleName());
        this.sessionFactory = sessionFactory;
    }

    @Override
    public Persona saveOne(Persona persona) {
        String generatedIdentifier = (String) sessionFactory.getCurrentSession().save(persona);
        logger.info("generatedIdentifier: {}", generatedIdentifier);
        return persona;
    }

...

Each crud method has sessionFactory.getCurrentSession().

With Mockito the following sentence:

when(sessionFactory.getCurrentSession().save(persona)).thenReturn(persona.getId());

always throws java.lang.NullPointerException. I've confirmed sessionFactory.getCurrentSession() is the point of the problem.

I already have read the following:

Thus the java.lang.NullPointerException was removed.

But I always get now:

org.mockito.exceptions.verification.TooManyActualInvocations: 
sessionFactory.getCurrentSession();
Wanted 1 time:
-> at com.manuel.jordan.repository.hibernate.PersonaHibernateRepositoryTest_.saveOneTest(PersonaHibernateRepositoryTest_.java:76)
But was 2 times. Undesired invocation:
-> at com.manuel.jordan.repository.hibernate.PersonaHibernateRepository.saveOne(PersonaHibernateRepository.java:43)

These two times happens due the mock invocation and target invocation.

Currently my configuration is:

private PersonaHibernateRepository personaHibernateRepository;
private SessionFactory sessionFactory;
private Session session;

...

@Before
public void setup(){
    sessionFactory = mock(SessionFactory.class);
    session = mock(Session.class);
    personaHibernateRepository = new PersonaHibernateRepository(sessionFactory);
    //Removes NullPointerException - 'A'
    when(sessionFactory.getCurrentSession()).thenReturn(session);
}

@Test
public void saveOneTest(){

    //java.lang.NullPointerException removed thanks to 'A'      
    when(sessionFactory.getCurrentSession().save(persona)).thenReturn(persona.getId());

    Persona persona_ = personaHibernateRepository.saveOne(persona);
    assertThat(persona_, is(persona));

    //B
    verify(sessionFactory).getCurrentSession().save(persona);
}

Just playing, if I change:

From: verify(sessionFactory).getCurrentSession().save(persona);

To: verify(sessionFactory, times(2)).getCurrentSession().save(persona); (observe times(2))

Again appears the java.lang.NullPointerException thrown now by verify(sessionFactory, times(2)).getCurrentSession().save(persona); (B)

Same exception if in @Before the when(sessionFactory.getCurrentSession()).thenReturn(session) is changed to doReturn(session).when(sessionFactory).getCurrentSession()

What is the correct configuration?

1 Answers
Related