1
votes

Test unitaire JUnit 5 pour JPAQuery

J'ai essayé de trouver une approche pour écrire un cas de test unitaire simple pour la fonction ci-dessous, mais je n'ai rien trouvé. La fonction utilise essentiellement la requête JPA sur une classe QueryDSL Q et renvoie le résultat sous forme de carte. Tout exemple de code suffirait. Comment se moquer de la requête JPA entière pour renvoyer une carte.

@Autowired
EntityManager entityManager;
public Map<Integer, Double> getUsersCategoryAppliedBudgetMap(int opportunityTypeId, LocalDate startDate,
            LocalDate endDate) {
        QApplications applicationPath = QApplications.applications;
        JPAQuery<ApplicationApprovals> query = new JPAQuery<>(entityManager);
        log.info("Executing Budget Query for opportunity type" + opportunityTypeId);
        return query.from(applicationPath).where(applicationPath.applicationStatus.id
                .in(PENDING_APPROVAL.getId(), SENT_BACK.getId(), APPROVED.getId(), PENDING_WITHDRAW_APPROVAL.getId(),
                        PENDING_COMPLETION_DOCUMENT.getId(), REVIEW_COMPLETION_DOCUMENT.getId(), COMPLETED.getId())
                .and(applicationPath.opportunity.opportunityTypes.id.eq(opportunityTypeId))
                .and(applicationPath.appliedDate.between(startDate.atStartOfDay(), endDate.atTime(LocalTime.MAX))))
                .groupBy(applicationPath.user.id)
                .transform(GroupBy.groupBy(applicationPath.user.id).as(applicationPath.cost.sum()));
    }


0 commentaires

3 Réponses :


-1
votes

Êtes-vous sûr de vouloir un test unitaire , i. e. un test qui se moque de votre couche de persistance? Que voudriez-vous vérifier exactement par ce test?

[Modifier: Comment cela s'est-il terminé comme une réponse plutôt que comme un commentaire?]


2 commentaires

Je veux augmenter la couverture du code, donc je dois écrire un cas de test unitaire.


Les métriques de réunion sont la mauvaise motivation pour écrire des tests. Rédiger des tests unitaires pour garantir un aspect du contrat ou pour reproduire, corriger et documenter un bug!



0
votes

Si vous utilisez spring-boot et que c'est des démarreurs et que vous tirez parti des référentiels Spring Data JPA, vous pouvez essayer d'utiliser @DataJpaTest pour configurer une instance H2 en mémoire et exécuter vos requêtes par rapport à cela pour vérifier votre code. Doc .


0 commentaires

-1
votes

Plutôt que d'avoir du code qui appelle new JPAQuery (entityManager); vous pouvez câbler une interface qui fournit le JPAQuery . Vous pouvez alors vous moquer de cette interface, donc le JPAQuery fourni est un simulacre, contrôlé par votre test.

voici un exemple de la manière dont l'interface fournit le nouvel objet:

@Test
public void valueReturnedFromNewObjectIsFromSuppliedMap() {

  //create a mock which will provide your new object
  Function<Map<String, Integer>, Map<String, Integer>> mockMapSupplier = mock(Function.class);

  //set up the object you want the mock to return
  Map<String, Integer> otherEntries = new HashMap<>();
  Integer alternativeValue = 1000;
  otherEntries.put(KEY, alternativeValue);

  //using Mockito, tell the mock when to return your expected response
  when(mockMapSupplier.apply(entries)).thenReturn(otherEntries);

  //create the class you want to test using your mock
  NewObject newObject = new NewObject(entries, mockMapSupplier);

  //verify it behaves as expected
  assertThat(newObject.getKeyForValue(KEY), is(alternativeValue));
}

puis dans votre test vous pouvez insérer une implémentation alternative de l'interface, vous permettant de fournir une maquette de l'objet que vous souhaitez contrôler:

@RequiredArgsConstructor
public static class NewObject {

  private final Map<String, Integer> entries; //Equivalent of EntityManager in example above
  private final Function<Map<String, Integer>, Map<String, Integer>> mapSupplier; // new dependency, which supplies the new object to be mocked

  public Integer getKeyForValue(String key) {
    //rather than calling myMap = new HashMap<>(entries) use the method call
    //equivalent replacement of: JPAQuery<ApplicationApprovals> query = new JPAQuery<>(entityManager)
    Map<String, Integer> myMap = mapSupplier.apply(entries);
    return myMap.get(key);
  }
}

Les exemples ci-dessus utilisent Mockito ( https://site.mockito.org ) pour fournir des objets simulés qui peuvent être contrôlés dans le test unitaire. Si vous n'êtes pas familier avec Mockito, je vous recommande de consulter la documentation et les exemples qu'ils fournissent pour comprendre ce qu'il fait et comment vous pouvez l'utiliser dans des tests pour vérifier le comportement de votre code.


1 commentaires

Veuillez donner des exemples, je ne suis pas votre code désolé