Search code examples
springunit-testingjparepositoryjunit4

How to unit test a jpa repository method?


I have coded a JPA repository method and I am now realizing it is impossible to unit test.

Can anyone please advise how to unit test the following method or how to refactor my repository so that it is unit-testable?

Here is the problematic method:

@Override
public List<Pli> findPlisByMultiField(String identifiant, Date dateReceptionFrom, Date dateReceptionTo, PaiementEnum paiement, AREnum ar, String numeroAR, FDVEnum FDV, ConteneurNum conteneurNum, StatutPli statut) {
    log.debug("findPlisByMultiField");

    CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
    CriteriaQuery<Pli> c = criteriaBuilder.createQuery(Pli.class);
    Root<Pli> pli = c.from(Pli.class);

    List<Predicate> criteria = new ArrayList<Predicate>();

    if (identifiant != null && !identifiant.trim().equals("")) {
        ParameterExpression<String> parameterIdentifiant = criteriaBuilder.parameter(String.class, "identifiant");
        Predicate conditionIdentifiant = criteriaBuilder.like(pli.<String> get("identifiant"), parameterIdentifiant);
        criteria.add(conditionIdentifiant);
    }

    if (dateReceptionFrom != null && dateReceptionTo != null) {
        ParameterExpression<Date> parameterDateReceptionFrom = criteriaBuilder.parameter(Date.class, "dateReceptionFrom");
        ParameterExpression<Date> parameterDateReceptionTo = criteriaBuilder.parameter(Date.class, "dateReceptionTo");
        Predicate conditionDateReception = criteriaBuilder.between(pli.<Date> get("dateReception"), parameterDateReceptionFrom, parameterDateReceptionTo);
        criteria.add(conditionDateReception);
    }

    if (paiement != null) {
        if (paiement.equals(PaiementEnum.IsPaiement)) {
            Predicate conditionPaiementEnum = criteriaBuilder.equal(pli.<PaiementEnum> get("paiement"), true);
            criteria.add(conditionPaiementEnum);
        } else {
            Predicate conditionPaiementEnum = criteriaBuilder.equal(pli.<PaiementEnum> get("paiement"), false);
            criteria.add(conditionPaiementEnum);
        }
    }

    if (ar != null) {
        if (ar.equals(AREnum.IsAR)) {
            Predicate conditionAREnum = criteriaBuilder.equal(pli.<AREnum> get("AR"), true);
            criteria.add(conditionAREnum);
        } else {
            Predicate conditionAREnum = criteriaBuilder.equal(pli.<AREnum> get("AR"), false);
            criteria.add(conditionAREnum);
        }
    }

    if (numeroAR != null && !numeroAR.trim().equals("")) {
        ParameterExpression<String> parameterNumeroAR = criteriaBuilder.parameter(String.class, "numeroAR");
        Predicate conditionNumeroAR = criteriaBuilder.like(pli.<String> get("numeroAR"), parameterNumeroAR);
        criteria.add(conditionNumeroAR);
    }

    if (FDV != null) {
        if (FDV.equals(FDVEnum.IsFDV)) {
            Predicate conditionFDVEnum = criteriaBuilder.equal(pli.<FDVEnum> get("FDV"), true);
            criteria.add(conditionFDVEnum);
        } else {
            Predicate conditionFDVEnum = criteriaBuilder.equal(pli.<FDVEnum> get("FDV"), false);
            criteria.add(conditionFDVEnum);
        }
    }

    if (conteneurNum != null) {
        ParameterExpression<ConteneurNum> parameterConteneurNum = criteriaBuilder.parameter(ConteneurNum.class, "conteneurNum");
        Predicate conditionConteneurNum = criteriaBuilder.equal(pli.<ConteneurNum> get("conteneurNum"), parameterConteneurNum);
        criteria.add(conditionConteneurNum);
    }

    if (statut != null) {
        ParameterExpression<StatutPli> parameterStatut = criteriaBuilder.parameter(StatutPli.class, "statut");
        Predicate conditionStatut = criteriaBuilder.equal(pli.<StatutPli> get("statut"), parameterStatut);
        criteria.add(conditionStatut);
    }

    if (criteria.size() == 0) {
        return Pli.findAllPlis();
    } else if (criteria.size() == 1) {
        c.where(criteria.get(0));
    } else {
        c.where(criteriaBuilder.and(criteria.toArray(new Predicate[0])));
    }

    TypedQuery<Pli> q = em.createQuery(c);
    if (identifiant != null && !identifiant.trim().equals("")) {
        q.setParameter("identifiant", "%" + identifiant + "%");
    }
    if (dateReceptionFrom != null && dateReceptionTo != null) {
        q.setParameter("dateReceptionFrom", dateReceptionFrom);
        q.setParameter("dateReceptionTo", dateReceptionTo);
    }

    if (numeroAR != null && !numeroAR.trim().equals("")) {
        q.setParameter("numeroAR", "%" + numeroAR + "%");
    }

    if (conteneurNum != null) {
        q.setParameter("conteneurNum", conteneurNum);
    }

    if (statut != null) {
        q.setParameter("statut", statut);
    }

    return q.getResultList();
}

Solution

  • Well, I don't think you will be able to Unit Test it as it's strictly specified, but you can make a test using an in memory database (look out for HSQL) so that the app don't need to actually go to the real database just for testing.

    That way you will be able to create an automated test that could run inside JUnit for example, mocking maybe only some of the methods.