Единичный тест на отказоустойчивость микропрофилей

Я использую Qurkus с Microprofile Fault Tolerance для реализации допустимости фолтов в соединении JDBC (Dremio ).

Я реализовал что-то вроде этого:

class Repository {

 
   private final DataSource dataSource; //initialized on constructor
   
   
   Collection<String> getData() exception SQLException {
      try (var conn = dataSource.getConnection();
             var stmt = conn.createStatement();
             var rs = stmt.executeQuery(sql)) {
           var result = new ArrayList<String>();

            while (rs.next()) {
                 result.add(rs.getString("data"));
            }
          return result;
      } catch(SQLException e) {
          //log and throw custom exception
      }
   }
}

class Service {
   @Inject
   Repository repo;

   public Collection<String> callService() {
            //other code that dosen't require retries
            try {
               var res = getData();
            } catch (Exception e) {
                 //log exception
                 throw new CustomException(e);
            }
            return res;
   }

   @Retry()
   private Collection<String> getData() throw Exception {
       return repo.getData();
  }

}

Теперь я пытаюсь проверить повторную попытку с помощью модульного теста. Я не нашел документации, относящейся к Microprofile Fault Tolerance.


@QuarkusTest
class ServiceTest {

    @Inject
    Service service;

    @InjectMock
    Repository repository;

    @Test
    void shouldHandleRetryWhenErrorOccursDuringQueryData() throws Exception {

        ArrayList<String> expectedResult = Lists.newArrayList("1","2");

        when(repository.getData())
             .thenThrow(new RuntimeException("Runtime Exception"))
             .thenReturn(expectedResult);

        Collection<String> executionResult = service.callService();

        assertIterableEquals(expectedResult, executionResult);

    }
}

Я ожидаю, что данные вернутся после одной попытки (первый вызов getData вернет ошибку). Вместо этого верните только ошибку.

Каков правильный способ проверки повторных попыток моего метода?


person Stefano Castoldi    schedule 15.09.2020    source источник


Ответы (1)


К сожалению, макеты нельзя использовать с аннотациями Fault Tolerance, потому что Mockito эффективно переопределяет все, что есть в исходном методе, включая аннотацию @Retry. Вы можете исправить это, переместив аннотацию @Retry на то, что вы не имитируете (метод Service.callService()), чтобы вместо этого был повторен метод callService, а при второй попытке вызов репозитория будет выполнен.

person Jan Martiška    schedule 16.09.2020
comment
ваше решение звучит хорошо, но в служебной функции у меня есть другой код, который не должен выполняться повторно при повторных попытках. - person Stefano Castoldi; 16.09.2020
comment
Хм, в этом случае я думаю, вам понадобится еще одна промежуточная оболочка вокруг репозитория, и к ней будет применена аннотация @Retry .. - person Jan Martiška; 16.09.2020
comment
Но есть также вопрос, является ли это вообще хорошей идеей, вы тестируете функцию повтора, встроенную в Quarkus, а не тестируете свой собственный бизнес-код. Это то, что рассматривается в тестовых наборах Quarkus. Так что ваш тест имеет смысл только в том случае, если вы действительно не доверяете команде Quarkus, что они тестируют должным образом;) - person Jan Martiška; 16.09.2020
comment
Я проверяю, что моя логика возвращает ошибки или данные даже при повторных попытках. Я не проверяю логику повтора. - person Stefano Castoldi; 16.09.2020