Search code examples
mockitocriteriaprivate-methods

Mockito - Testing method that calls private methods


I was trying to find solution but haven't found yet. I tried to test public method which has calls of the couple of private ones inside. One of the problem that private method retrieves Hibernate's Criteria by generic method that in its turn retrieves it through chain of another generic methods. Please take a look at the code below. Frankly I'm not sure that it is possible to test that case but if anyone has ideas please suggest them:

ConcreteDao

public class ConcreteDao extends EntityDao<ConcreteEntity> {

    public Class<ConcreteEntity> getClassType() {
        return ConcreteEntity.class;
    }

}

EntityDao

public abstract class EntityDao<T> extends AbstractDao<T>{

    public List<T> getEntityByFilter(EntityFilter filter) {
        Criteria criteria = getCriteriaByFilter(filter.getFilters());
        criteria.setMaxResult(filter.getMaxResult());
        criteria.setFirstResult(filter.getFirstResult());
        criteria.addOrder(Order.asc(filter.getSortedField()));
        criteria.list();
    }

    private Criteria getCriteriaByFilter(List<CustFilter> filters) {
        Criteria criteria = getCriteria();
        for (CustFilter filter : filters) {
            filter.addrestrictionToCriteria(criteria, filter.getProperty(), filter.getValue());
        }
        return criteria;
    }

}

AbstractDao

public abstract class AbstractDao<T> {

    private EntityManagerFactory entityManagerFactory;

    public abstract getClassType();

    public Criteria getCriteria() {
        return getSession().createCriteria(getClassType());
    }

    public Session getSession() {
        Session session = (Session) getEntityManager().getDelegate();
        return session;
    }

    public EntityManager getEntityManager() {
        entityManagerFactory.getEntityManager();
    }

}

Test class

@RunWith(MockitoJUnitRunner.class)
public class ConcreteDaoTest {

    @Mock
    private EntityManager entityManager;

    @Mock
    private Session session;

    @Mock
    private Criteria criteria;

    private List<CustFilter> filters;

    private EntityFilter entityFilter;

    private List<ConcreteEntity> resultList;

    @InjectMocks
    private ConcreteDao concreteDao = new ConcreteDao;

    public void init() {
        filters = new ArrayLis<CustFilter>();
        CustFilter custFilter = new CustFilter();
        //fill filter;
        filters.add(custFilter);

        entityFilter = new EntityFilter();
        //fill entityFilter
        entityFilter.setFilters(filters);

        ConcreteEntity concreteEntity = new ConcreteEntity();
        resultList = new ArrayList<ConcreteEntity>();
        resultList.add(concreteEntity);

    }


    @Test
    public void getEntityByFilterTest() {
        when(concreteDao.getEntityManager).thenReturn(entityManager);
        when(concreteDao.getSession()).thenReturn(session);
        when(concretedao.getCriteria()).thenReturn(criteria);

        when(filter.getFilters()).thenReturn(filters);
        when(filter.getMaxResult()).thenReturn(10);
        when(filter.getFirstResult()).thenReturn(0);
        when(filter.getSortedField()).thenReturn("firstName");
        when(criteria.list()).thenReturn(resultList);

        List<ConcreteEntity> result = concreteDao.getEntityByFilter(entityFilter);
        Assert.assertThen(result. is(notNullValue()));
    }

} 

Solution

  • With Mockito, you cannot mock private method calls. Try PowerMockito with which you can mock any kinds of methods like static methods, private methods, local method instantiations and so on.