我正在使用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(
导致这种情况的原因是什么?
答案 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);