2017-01-02 1 views
1

Допустит, что у меня есть коллекция книг. (Книга извлекается из упругого поиска)Как проверить, если коллекция объектов содержит свойство объекта в заданном порядке

class Book { 

String name; 
String author; 

// 10 other properties 

} 

Теперь в моем JUnit мне нужно проверить ли книги в порядке возрастания от name (последнее мне нужно проверить то же самое со всеми остальными 11 объектов)

можно ли проверить порядок book без создания Book объекта в моем JUnit тестовый класс? если да, то как?

ответ

1

взглянуть на библиотеку AssertJ для тестирования, он имеет с ним вы можете определить если, например, список упорядочен

имен экстракта из книг:

List<String> names = books.stream() 
          .map(book -> book.getName()) 
          .collect(Collectors.toList()); 

впоследствии использовать метод AssertJ для проверки заказа, например:

Assertions.assertThat(names).isSorted() 

, конечно, вы можете также предоставить свои собственные компараторов и использовать isSortedAccordingTo метод

для справки http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/api/ArraySortedAssert.html

примечание: я не сделал попробуйте скомпилировать код

1

Это не JUnit конкретных, но, возможно, this answer в этом так помогает:

Это предполагает этот общий метод:

public static <T extends Comparable<? super T>> boolean isSorted(final Iterable<T> iterable) { 
    Iterator<T> iter = iterable.iterator(); 
    if (!iter.hasNext()) { 
     return true; 
    } 
    T t = iter.next(); 
    while (iter.hasNext()) { 
     T t2 = iter.next(); 
     if (t.compareTo(t2) > 0) { 
      return false; 
     } 
     t = t2; 
    } 
    return true; 
} 
0

В основном я вижу два варианта: вы можете использовать библиотеку, которая будет писать (некоторые) tes ts более удобно, и вы можете положиться на простой JUnit и делать все остальное «вручную».

Для опции библиотеки это не мой опыт, но я знаю, что есть номер на выбор. Что pezetem пишет в another answer о звуках AssertJ, многообещающих, в частности isSortedAccordingTo(). Это требует от вас написать Comparator для каждой сортировки, которую вы хотите проверить. Я бы неплохо посмотрел на разные библиотеки, не обращая внимания на другие тесты, кроме этого, прежде чем сделать осознанный выбор.

Если вы предпочитаете, чтобы не зависеть от библиотеки, с целью прямо сейчас, я предлагаю вам написать себе вспомогательный метод как это:

private static <T extends Comparable<? super T>> boolean isSortedBy(Function<Book, T> getMethod, List<Book> list) { 
    if (list.isEmpty()) { 
     return true; 
    } 
    Iterator<Book> bit = list.iterator(); 
    T attr = getMethod.apply(bit.next()); 
    while (bit.hasNext()) { 
     T nextAttr = getMethod.apply(bit.next()); 
     if (nextAttr.compareTo(attr) < 0) { 
      return false; 
     } 
     attr = nextAttr; 
    } 
    return true; 
} 

Вы признать логику от this answer, но я закручивается подпись метода, чтобы соответствовать вашей потребности здесь. Теперь ваш тест просто:

assertTrue(isSortedBy(Book::getName, listOfBooks)); 

Две ноты, хотя:

  1. Я предполагаю, что ваш Book класса имеет добытчик, и есть причины, которые вы можете добавить их, а не только для единичный тест. Если нет, вы можете использовать isSortedBy(b -> b.name, listOfBooks).
  2. Когда вы сказали о коллекции, я предполагаю, что вы имели в виду список.Другие типы коллекций (например, наборы) могут не иметь порядка, поэтому может не иметь смысла проверять, отсортированы ли они.

Если вы хотите, чтобы ваш метод более общий характер, вы можете добавить еще один параметр типа, чтобы позволить списки других вещей, чем книги:

private static <E, T extends Comparable<? super T>> boolean isSortedBy(Function<E, T> getMethod, List<E> list) 

Со своей стороны, я буду ждать, пока я не вижу необходимости, хотя.

При написании модульных тестов я считаю, что стоит подумать о том, как тестовые сбои сообщаются тестеру, какая информация ему понадобится, если тест не удастся. Только знание списка не было отсортировано по атрибуту, который он должен сортировать, возможно, не так полезен. Если вы список не долго, я думаю, что вы можете просто сбросить весь список, как сообщение:

assertTrue(listOfBooks.toString(), isSortedBy(Book::getName, listOfBooks)); 

(. Вы хотите, чтобы убедиться, что ваш Book класс имеет метод toString для этого, чтобы быть полезным) Есть, конечно, чтобы сделать более утонченную отчетность о сбоях, если у вас есть вспомогательный метод, возвращайте конкретное сообщение, а не только true или false.

Смежные вопросы