In Unit Test Class:
@Mock
EntityManager entityManager;
@Mock
Root<RedFox> redFoxRoot;
@Mock
Expression expression;
@Mock
Path path;
@Mock
Predicate predicate;
@Test
public void filterTest(){
TypedQuery<RedFox> redFoxQuery = (TypedQuery<RedFox>) Mockito.mock(TypedQuery.class);
CriteriaQuery<RedFox> redFoxCriteriaQuery = Mockito.mock(CriteriaQuery.class);
Mockito.when(redFoxCriteriaQuery.where(Mockito.any(Predicate[].class)))
.thenReturn(redFoxQuery);
Mockito.when(redFoxCriteriaQuery.orderBy(Mockito.anyList())).thenReturn(redFoxCriteriaQuery);
CriteriaBuilder builder = Mockito.mock(CriteriaBuilder.class);
Mockito.when(redFoxRoot.get("isDeleted")).thenReturn(path);
Mockito.when(path.isNull()).thenReturn(predicate);
Mockito.when(builder.literal(Mockito.any())).thenReturn(expression);
Mockito.when(redFoxCriteriaQuery.from(RedFox.class)).thenReturn(redFoxRoot);
Mockito.when(entityManager.createQuery(redFoxCriteriaQuery)).thenReturn(redFoxQuery);
List<RedFox> redFoxs = new ArrayList<>();
RedFox redFox = new RedFox();
redFox.setTitle("abc");
redFox.setRedFoxStatus("");
redFox.setId(UUID.randomUUID());
redFoxs.add(redFox);
Mockito.when(redFoxQuery.getResultList()).thenReturn(redFoxs);
}
In class service:
public List<RedFox> filter(){
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<RedFox> redFoxCriteriaQuery = builder.createQuery(RedFox.class);
Root<RedFox> root = redFoxCriteriaQuery.from(RedFox.class);
redFoxCriteriaQuery.select(root);
List<Predicate> searchClause = new ArrayList<>();
searchClause.add(builder.isFalse(root.get("isDeleted")));//root cause error
Predicate[] searchClauses = searchClause.toArray(Predicate[]::new);
Query executingQuery = em.createQuery(redFoxCriteriaQuery.where(searchClauses)
.orderBy(orderBys));//Null pointer exception
List<RedFox> resultData = executingQuery
.getResultList();
..............................
}
My problem is when I comment the searchClause.add(builder.isFalse(root.get("isDeleted"))), it mean that the searchClauses is empty Array, then the code execute successfully.
But when the search clauses is not empty, then redFoxCriteriaQuery.where(searchClauses) not use the result I mocked but return null, and it will cause the null pointer exception.
I've been tucked 2 days but still don't know why so please help me with this issue.
Change
Mockito.when(redFoxCriteriaQuery.where(Mockito.any(Predicate[].class)))
.thenReturn(redFoxQuery);
to
Mockito.when(redFoxCriteriaQuery.where((Predicate[].class) Mockito.any()))
.thenReturn(redFoxQuery);
So, it can work with any non null object. But if you write Mockito.any(Predicate[].class), then it just compare 2 array with type Predicate. And of course, 2 array cannot equal although all the elements in each array are equal.