使用TypedQuery的Mockito空指针?

时间:2016-08-09 11:34:11

标签: java unit-testing nullpointerexception mockito

我正在使用Mockito来模拟Java持久性查询的结果集:

代码被嘲笑:

 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(

导致这种情况的原因是什么?

1 个答案:

答案 0 :(得分: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);