Модульный тест JUnit 5 для JPAQuery - PullRequest
1 голос
/ 18 июня 2020

Я пытался найти подход к написанию простого модульного теста для функции ниже, но не мог ничего понять. Функция в основном использует запрос JPA для класса QueryDSL Q и возвращает результат в виде карты. Подойдет любой образец кода. Как издеваться над всем запросом JPA, чтобы вернуть карту.

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

Ответы [ 3 ]

0 голосов
/ 18 июня 2020

Если вы используете spring -boot, и он запускается и использует репозитории Spring Data JPA, вы можете попробовать использовать @DataJpaTest для настройки экземпляра H2 в памяти и запустить свои запросы для проверки вашего кода. До c.

0 голосов
/ 18 июня 2020

Вместо кода, который вызывает new JPAQuery<>(entityManager);, вы можете подключить интерфейс, который предоставляет JPAQuery. Затем вы можете имитировать этот интерфейс, поэтому предоставленный JPAQuery является имитацией, управляемой вашим тестом.

вот пример того, как интерфейс предоставляет новый объект:

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

затем в вашем test, вы можете вставить альтернативную реализацию интерфейса, позволяющую создать имитацию объекта, которым вы хотите управлять:

@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, я рекомендую посмотреть документацию и примеры, которые они предоставляют, чтобы понять, что он делает и как вы можете использовать его в тестах для проверки поведения вашего кода.

0 голосов
/ 18 июня 2020

Вы уверены, что хотите пройти тест unit , т.е. е. тест, высмеивающий ваш уровень устойчивости? Что именно вы хотите проверить с помощью этого теста?

[Edit: Как это закончилось как ответ, а не как комментарий?]

...