1

I am using Mockito to mock the result set of a Java Persistence Query:

Code being mocked:

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

 }

test code:

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

I am getting a null pointer error on the line:

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

What could be causing this?

java123999
  • 6,974
  • 36
  • 77
  • 121
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – GhostCat Aug 09 '16 at 11:38
  • @GhostCat what do you mean? please explain – java123999 Aug 09 '16 at 11:38
  • Maybe I a was a bit too quick. But the point is: on that one line, you have at least two objects that could give you the NPE. A) *persistence* B) the result of the call to entityManager() C) then the result of createQuery(). Long story short: you have to make sure that each of those calls returns something that is not null. – GhostCat Aug 09 '16 at 11:40
  • 1
    try with when(query.setParameter("name", name)).thenReturn(query); instead of when(query.setParameter(1, name)).thenReturn(query); – Nicolas Filotto Aug 09 '16 at 11:45
  • Are you sure that persistence.entityManager() returns something ? – Nicolas Filotto Aug 09 '16 at 11:46
  • Thanks that fixed it, but can you explain why Nicolas? – java123999 Aug 09 '16 at 11:46
  • check your query it calls .setParameter("name", name) not .setParameter(1, name) such that you don't mock the right method – Nicolas Filotto Aug 09 '16 at 11:48

1 Answers1

5

Your bug is here:

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

it should be

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

Indeed in your request you call .setParameter("name", name) not .setParameter(1, name) so you don't mock the right method and by default a non mocked method will return null which is why you get a NPE.

Anyway it doesn't seem to be the right approach as it is very error prone since you need to couple too much your test case with your implementation, you should rather move your query in a dedicated method and then mock this method.

We should have something like:

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

Then you will be able to mock this method as next:

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

MyDAO dao = mock(MyDAO.class);
when(dao.findByName(name)).thenReturn(personList);
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122