2016-08-09 35 views
-1

我使用的Mockito嘲笑結果集的Java持久性查詢:Mockito空指針與TypedQuery?

代碼被嘲笑:

public void queryMethod(String name){ 
    List<Person> result = persistence.entityManager().createQuery(
        "Select p from Person p + 
          " where p.name= :uniqueId" , Person.class) 
        .setParameter("name", name) 
        .getResultList(); 

} 

測試代碼:

String name = "anyName"; 
Person person = mock(Person.class); 
List<Person> personList = new ArrayList<>(); 
personList.add(person); 

    TypedQuery query = mock(TypedQuery.class); 
    when(entityManager.createQuery(anyString(), Matchers.<Class<Object>>anyObject())).thenReturn(query); 
    when(query.setParameter(1, name)).thenReturn(query); 
    when(query.getResultList()).thenReturn(personList); 

我得到一個空行指針錯誤:

List<Person> result = persistence.entityManager().createQuery(

什麼可能導致這種情況?

+0

的可能的複製[什麼是空指針異常,以及如何解決它?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – GhostCat

+0

@GhostCat你是什麼意思?請解釋 – java123999

+0

也許我有點太快了。但重點是:在這一行中,至少有兩個對象可以給你NPE。 A)*持久性* B)調用entityManager()的結果C),然後是createQuery()的結果。長話短說:你必須確保每個這樣的調用都返回非空的東西。 – GhostCat

回答

2

你的錯誤是在這裏:

when(query.setParameter(1, name)).thenReturn(query); 

應該

when(query.setParameter("name", name)).thenReturn(query); 

事實上,在您的要求,您撥打.setParameter("name", name).setParameter(1, name)所以你不要嘲笑正確的方法,默認情況下非嘲笑方法將返回null這就是爲什麼你得到一個NPE。

無論如何,它似乎並不是正確的方法,因爲它非常容易出錯,因爲您需要將您的測試用例與您的實現結合太多,所以您應該在專用方法中移動您的查詢,然後模擬此方法。

我們應該有這樣的事情:

public List<Person> findByName(String name) { 
    return persistence.entityManager().createQuery(
       "Select p from Person p + 
         " where p.name= :uniqueId" , Person.class) 
       .setParameter("name", name) 
       .getResultList(); 
} 

然後你就可以嘲笑爲接下來的這個方法:

Person person = mock(Person.class); 
List<Person> personList = new ArrayList<>(); 
personList.add(person); 

MyDAO dao = mock(MyDAO.class); 
when(dao.findByName(name)).thenReturn(personList);