簡體   English   中英

JUnit 5 JPAQuery 的單元測試

[英]JUnit 5 Unit test for JPAQuery

我一直在嘗試找到一種方法來為下面的 function 編寫一個簡單的單元測試用例,但無法弄清楚任何事情。 function 基本上使用 JPA 查詢 QueryDSL Q class 並將結果返回為 Z46F3ZEA056CAA3128B7C 任何示例代碼就足夠了。 如何模擬整個 JPA 查詢以返回 Map。

@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()));
    }

如果您使用 spring-boot 並且它是啟動器並利用 Spring 數據 JPA 存儲庫,那么您可以嘗試使用@DataJpaTest來設置一個針對該實例運行的內存中代碼。 文檔

您確定要進行單元測試嗎? e. 測試mocking 你的持久層? 您究竟想通過該測試驗證什么?

[編輯:這最終是如何成為答案而不是評論的?]

而不是調用new JPAQuery<>(entityManager); 您可以連接提供JPAQuery的接口。 然后您可以模擬此接口,因此提供的 JPAQuery 是一個模擬,由您的測試控制。

這是接口如何提供新 object 的示例:

@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);
  }
}

然后在您的測試中,您可以插入接口的替代實現,允許您提供要控制的 object 的模擬:

@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));
}

上面的示例使用 Mockito ( https://site.mockito.org ) 提供可以在單元測試中控制的模擬對象。 如果您不熟悉 Mockito,我建議您查看它們提供的文檔和示例,以了解它的作用以及如何在測試中使用它來驗證代碼的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM