2017-08-16 12 views
1

私は、次のしている:Hibernateの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; 
    } 

... 

を各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) 

これらの2回は、モック呼び出しとターゲットの呼び出しにより起こります。

現在、私の設定は次のとおりです。

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を表示されますnow by verify(sessionFactory, times(2)).getCurrentSession().save(persona);B

同じ例外@Beforewhen(sessionFactory.getCurrentSession()).thenReturn(session)は正しい構成で何doReturn(session).when(sessionFactory).getCurrentSession()

に変更された場合はどうなりますか? sessionインスタンスではありませんsessionFactoryに焦点を当てるべきであるあなたが正しくsessionFactory.getCurrentSession()があなたの主張にので、それらから呼び出されたときに嘲笑sessionインスタンスを返すようにMockitoを伝えるsetup()方法で

+0

'(のSessionFactory).getCurrentSessionを()検証(ペルソナ)を保存;' '検証(sessionFactory.getCurrentSession())でなければなりません(ペルソナ)を保存します。あなたの提案が働く' – Chriss

答えて

1

。たとえば:

@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); 
} 
+0

おかげで、。。私は何かが私のために混乱していると私はこのチュートリアルでこのアプローチや動作を見たことがない、私はMockitoが必須であると思った 'when/thenReturn'と' verify **は**同じ**コードが'saveOne'メソッドです。 'sessionFactory.getCurrentSession()。save(人物));'。 –

+0

同じメソッド・アンダー・テストに対して 'when/thenReturn' **と**' verify'の両方を使うことは必須ではありません。'verify'呼び出しは、あなたの模擬オブジェクトでメソッドが呼び出されたことをアサートし、そのメソッド呼び出しに渡された引数を確認することを可能にします。 'when/thenReturn'は間接的に同じことを可能にしますが、実際のオブジェクトのようにそのモックされたオブジェクトをコードフローに参加させる追加の副作用を伴います。だから、同じことを達成するために使うこともできますが、一方が他方に当てられているシナリオがありますが、それを一緒に使う必要はないのです。 – glytching

+0

興味深くて、説明に感謝して、それが現在のmockitoドキュメントに反映されているかどうか不思議です。ドキュメントを改善するために問題を作成することを検討しています。 –

関連する問題