dimanche 16 juillet 2023

Check if Collection of DTOs sorted by a given field

I have to write tests for a pagination and sorting GET ALL endpoint that I have. The following is the simple DTO that I am working with:

public class TransactionDto {
  private Long id;
  private Long sourceAccountId;
  private Long targetAccountId;
  private BigDecimal amount;
  private Currency currency;
}

Of importance to this discussion is that all of those fields are Comparable, including the type Currency, which is an enum I have created with about 300 different currency symbols.

Now, I want to ensure that a REST controller endpoint has returned a Collection of these TransactionDto instances in a sorted manner. After reading here I learned of Guava's Comparators class and, specifically, the isInOrder method (doc link).

I have to begin with the field name of TransactionDto to sort by, and I also have this simple SortOrder enum to designate ascending or descending sort order:

public enum SortOrder {
    ASC, DESC
}

This is what I have so far, and I am stuck on the fact that the Method.invoke() method returns raw Object instances.

private boolean collectionIsSortedByFieldInGivenDirection(Collection<TransactionDto> transactionDtos,
                                                            String sortByField, SortOrder sortOrder){
    return Comparators.isInOrder(transactionDtos, (t1, t2) -> compareFieldsInGivenOrder(t1, t2, sortByField, sortOrder));
}

private int compareFieldsInGivenOrder(TransactionDto transactionOne, TransactionDto transactionTwo,
                                        String sortByField, SortOrder sortOrder){
    try {
      PropertyDescriptor propertyDescriptor = new PropertyDescriptor(sortByField, TransactionDto.class);
      Method appropriateGetter = propertyDescriptor.getReadMethod();
      Object transactionOneValue = appropriateGetter.invoke(transactionOne);
      Object transactionTwoValue = appropriateGetter.invoke(transactionTwo);
      // Not much I can do with raw Objects...
    } catch (IntrospectionException | InvocationTargetException | IllegalAccessException e) {
      throw new RuntimeException(e.getMessage());
    }
}

I need to somehow retrieve variables of the appropriate type, which, as shown above, will be a type whose instances are Comparable with instances of the same type. I have also fiddled a bit with the Field.getType() method after reading through this answer but I haven't had much luck. Any ideas?





Aucun commentaire:

Enregistrer un commentaire