正确的配置来模拟Hibernate的sessionFactory.getCurrentSession()

时间:2017-08-16 02:21:50

标签: java unit-testing junit mockito

我有以下内容:

@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;
    }

...

每个crud方法都有sessionFactory.getCurrentSession()

使用Mockito以下句子:

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

始终抛出java.lang.NullPointerException。我已经确认sessionFactory.getCurrentSession()是问题的关键。

我已经阅读了以下内容:

因此删除了java.lang.NullPointerException

但我现在总是得到:

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)

这两次是由于模拟调用和目标调用而发生的。

目前我的配置是:

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);
}

只是在玩,如果我改变:

来自:verify(sessionFactory).getCurrentSession().save(persona);

收件人:verify(sessionFactory, times(2)).getCurrentSession().save(persona);(观察times(2)

java.lang.NullPointerException verify(sessionFactory, times(2)).getCurrentSession().save(persona);B)再次显示@Before抛出现在

如果when(sessionFactory.getCurrentSession()).thenReturn(session) doReturn(session).when(sessionFactory).getCurrentSession()更改为hadoop job -kill <Job-ID>

,则同样例外

正确的配置是什么?

1 个答案:

答案 0 :(得分:1)

setup()方法中,您正确地告诉Mockito在调用session时返回模拟的sessionFactory.getCurrentSession()实例,因此在断言上应该关注session实例sessionFactory。例如:

@Test
public void saveOneTest(){
    // you have already told Mockito to return this session instance when sessionFactory.getCurrentSession() is 
    // invoked so now your when (and optionally verify) should focus on session rather than on sessionFactory
    when(session.save(persona)).thenReturn(persona.getId());

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

    verify(session).save(persona);
}