@Transactional
public List<Object[]> findAll() {
Session session = sessionFactory.getCurrentSession();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Object[]> query = criteriaBuilder.createQuery(Object[].class);
Root<TableA> aRoot = query.from(TableA.class);
Root<TableB> bRoot = query.from(TableB.class);
Root<TableC> cRoot = query.from(TableC.class);
query.multiselect(aRoot.get("type"), cRoot.get("fieldId"), aRoot.get("fieldId"),
aRoot.get("fieldId"), aRoot.get("name"), aRoot.get("name"),
aRoot.get("average"), aRoot.get("average"));
query.where(criteriaBuilder.equal(bRoot.get("fieldId"), cRoot.get("fieldId")),
criteriaBuilder.in(bRoot.<String>get("type")).value("ABC").value("DFG"),<-----NullPointerException Here
criteriaBuilder.equal(bRoot.get("type"), aRoot.get("type")));
query.distinct(true);
return session.createQuery(query).getResultList();
}
This method has been censored but it works perfectly. My problem is completing the unit test to cover the code so I can push to our repository.
@Before
@Override
public void setup() {
super.setup();
}
@InjectMocks
@Spy
Dao dao;
@Mock
SessionFactory sessionFactory;
@Mock
Session mockSession;
@Mock
CriteriaBuilder criteriaBuilder;
@Mock
CriteriaQuery<Object> query;
@Mock
Root<TableA> mockARoot;
@Mock
Root<TableB> mockBRoot;
@Mock
Root<TableC> mockCRoot;
@Mock
Query<Object> result;
@Test
public void findAll() {
Mockito.when(sessionFactory.getCurrentSession()).thenReturn(mockSession);
Mockito.when(mockSession.getCriteriaBuilder()).thenReturn(criteriaBuilder);
Mockito.when(criteriaBuilder.createQuery(Mockito.anyObject())).thenReturn(query);
Mockito.when(query.from(TableA.class)).thenReturn(mockARoot);
Mockito.when(query.from(TableB.class)).thenReturn(mockBRoot);
Mockito.when(query.from(TableC.class)).thenReturn(mockCRoot);
Mockito.when(mockSession.createQuery(query)).thenReturn(result);
dao.findAll();
}
I believe the In clause is expecting an expression or predicate. Do I need to mock and pass in other interfaces to get this to work? I would really like to add this style of query construction to our code-base but I cannot complete the junit test. Any assistance would be much appreciated!
CodePudding user response:
As far as I know, people dont use mockito to test the Dao layer. It should be tested as an integration test.
Regarding mockito, we should mock the layers only where the object other classes are used within the method for example in your code, the variable sessionFactory is an object of other class used in this findAll method in Dao.
We should mock that class and not the variables which initialized within the mehtod(local variables).
P.S, full error stack trace would be more helpful to address
CodePudding user response:
You don't mock all your methods calls... query.multiselect
, aRoot.get("fieldId")
... As you are mocking your object, you are reponsible to mock all the needed method calls.