Java 正确配置模拟Hibernate';s sessionFactory.getCurrentSession()
我有以下资料:Java 正确配置模拟Hibernate';s sessionFactory.getCurrentSession(),java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,我有以下资料: @Repository @Transactional @HibernateProfile public class PersonaHibernateRepository implements PersonaRepository { private static final Logger logger = LoggerFactory.getLogger(PersonaHibernateRepository.class.getSimpleName()); priv
@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()
是问题的症结所在
我已经读过以下内容:
@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;
}
...
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);
}
只是玩,如果我改变:
From:verify(sessionFactory).getCurrentSession().save(persona)代码>
到:verify(sessionFactory,times(2)).getCurrentSession().save(persona)代码>(遵守次(2)
)
再次出现verify(sessionFactory,times(2)).getCurrentSession().save(persona)引发的java.lang.NullPointerException
异常now代码>(B
)
如果在@Before
中的when(sessionFactory.getCurrentSession())中出现相同的异常。然后将return(session)
更改为doReturn(session).when(sessionFactory.getCurrentSession()
正确的配置是什么?在setup()
方法中,当调用sessionFactory.getCurrentSession()
时,您正确地告诉Mockito返回模拟的会话
实例,因此在断言中应该关注会话
实例,而不是会话工厂
。例如:
@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);
}
谢谢,你的建议奏效了,现在有些东西让我感到困惑,而且我在none教程中从未见过这种方法或行为,我认为对于Mockito来说,必须执行when/thenReturn
和verify
以尊重或反映saveOne
方法中使用的相同代码<代码>sessionFactory.getCurrentSession().save(角色)代码>。考虑添加一个关于社区的额外解释,对于相同的测试方法,不必同时使用<代码>何时返回/<代码>和<代码>验证< /代码>。verify
调用允许您断言对模拟对象调用了方法,并验证传递给该方法调用的参数。when/thenReturn
间接地允许相同的事情,但额外的副作用是允许模拟对象像真实对象一样参与代码流。因此,它们可以用来实现同样的目标,虽然也确实存在这样的情况,即一个场景优于另一个场景,但它们不一定必须一起使用。有趣的是,感谢您的解释,只是好奇它是否反映在当前的mockito文档中。我正在考虑创建一个问题来改进它的文档。同样地,saveOne
方法包含sessionFactory.getCurrentSession().save(persona)
语句,但是在when/thenReturn
和verify
调用中,它们直接围绕会话运行。verify(sessionFactory.getCurrentSession().save(persona);
应该是验证(sessionFactory.getCurrentSession()).save(persona);