Reputation: 33
I have created a mock junit test case for below method
Method:
@Override
public List retrieveListByUserId(Users users) {
Session session = this.sessionFactory.getCurrentSession();
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<CredentialDocments> criteria = builder.createQuery(CredentialDocments.class);
Root<CredentialDocments> credentialRoot = criteria.from(CredentialDocments.class);
criteria.select(credentialRoot).where(builder.equal(credentialRoot.get(USERS), users)).distinct(true);
criteria.orderBy(builder.desc(credentialRoot.get(PropertyConstant.UPLOADED_TS)));
return session.createQuery(criteria).getResultList();
}
Test Case:
package com.xyz.dao.test;
import static org.mockito.Mockito.when;
import java.util.ArrayList; import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
public class CredentialDocTest {
@InjectMocks
CredentialDocDAO credentialDocDAO = new CredentialDocDAOImpl();
@Mock
SessionFactory sessionFactory;
@Mock
Session session;
@Mock
CriteriaBuilder builder;
@Mock
CriteriaQuery<CredentialDocments> criteria;
@Mock
Root<CredentialDocments> credentialRoot;
@Mock
Path<Object> path;
private CredentialDocments credentialDocument;
private List<CredentialDocments> credentialDocumentList;
@Before
public void setUp() throws Exception {
credentialDocument = new CredentialDocments();
credentialDocumentList = new ArrayList<>();
credentialDocument.setDocId(1);
credentialDocument.setDocNm("Doc1");
Users users = new Users();
users.setUserId("jscrotestpi");
credentialDocument.setUsers(users);
credentialDocumentList.add(credentialDocument);
when(sessionFactory.getCurrentSession()).thenReturn(session);
when(session.getCriteriaBuilder()).thenReturn(builder);
when(builder.createQuery(CredentialDocments.class)).thenReturn(criteria);
when(criteria.from(CredentialDocments.class)).thenReturn(credentialRoot);
}
@Test
public void testRetrieveListByUserId() {
criteria.select(credentialRoot);
when(credentialRoot.get("users")).thenReturn(path);
criteria.where(builder.equal(credentialRoot.get("users"), credentialDocument.getUsers())).distinct(true);
credentialDocDAO.retrieveListByUserId(credentialDocument.getUsers());
List<CredentialDocments> actualCredentialDocList = session.createQuery(criteria).getResultList();
Assertions.assertEquals(credentialDocumentList, actualCredentialDocList);
Assertions.assertEquals(1, actualCredentialDocList.size());
}
}
When i execute the above test case, Nullpointer Exception is throwing for credentialRoot.get("users") in below line criteria.where(builder.equal(credentialRoot.get("users"), credentialDocument.getUsers())).distinct(true);
Can you please help us to fix this problem. Thanks in advance.
Upvotes: 0
Views: 1403
Reputation: 32517
When a mock is returning a mock that returns a mock is an indication to me of either bad implementation desing, or bad test design (or both). Your test case will not test the behavior or contract that your component should have but will rather confirm that the code does what it does effectively testing nothing.
What if you decide that you will not use the CriteriaAPI but JPQL? Contract will not change, method shouldretrieveListByUserId
should return exactly the same thing. If so, then the test should not change neither. But you will have to rewrite it as there is no CriteriaAPI there any more. What will your mock then? This is bad.
Your case is perfect example of what could be tested using inmemory database to test your repository contract and not its implementation.
As you can see now, test itself and implementation of mocks in tests are more complicated then tested component itself, and not even work as intended - now you have to debug test scenario and mocks which is just bad.
Upvotes: 0