Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正确配置模拟Hibernate';s sessionFactory.getCurrentSession()_Java_Unit Testing_Junit_Mockito - Fatal编程技术网

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