2016-08-09 90 views
-1

ich Mockito bin mit dem Ergebnismenge einer Java Persistence Query zu verspotten:Mockito Nullzeiger mit TypedQuery?

-Code verspottet:

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

} 

Testcode:

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

Ich erhalte ein Nullzeigerfehler in der Zeile:

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

Was könnte das verursachen?

+0

Mögliche Duplikat [Was für eine Nullpointer ist, und wie kann ich es beheben ?] (http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-fix-it) – GhostCat

+0

@GhostCat was meinst du? Bitte erläutern Sie – java123999

+0

Vielleicht war ich ein bisschen zu schnell. Aber der Punkt ist: Auf dieser einen Linie haben Sie mindestens zwei Objekte, die Ihnen die NPE geben könnten. A) * Persistenz * B) das Ergebnis des Aufrufs von entityManager() C) dann das Ergebnis von createQuery(). Lange Rede, kurzer Sinn: Sie müssen sicherstellen, dass jeder dieser Aufrufe etwas zurückgibt, das nicht null ist. – GhostCat

Antwort

2

Ihr Fehler ist hier:

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

es

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

der Tat in Ihrer Anfrage rufen Sie .setParameter("name", name) nicht .setParameter(1, name) so spotten Sie nicht über die richtige Methode und wird standardmäßig ein nicht verspottet Methode wird null zurückgeben, weshalb Sie eine NPE erhalten.

Trotzdem scheint es nicht der richtige Ansatz zu sein, da es sehr fehleranfällig ist, da Sie Ihren Testfall zu sehr mit Ihrer Implementierung koppeln müssen. Stattdessen sollten Sie Ihre Abfrage in einer dedizierten Methode verschieben und dann diese Methode vortäuschen .

Wir sollten so etwas wie haben:

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

Dann werden in der Lage Sie diese Methode als nächstes zu verspotten:

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

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